移动 'micropost feed' 后损坏 Rails 集成 - 预计至少有 1 个元素匹配 "div#error_explanation",找到 0

Broken Rails integration after moving 'micropost feed' - Expected at least 1 element matching "div#error_explanation", found 0

遵循 Michael Hartl 的 Rails 教程后,我将 'micropost feed' 从 / 移至 /members,现在当我提交一个 post 时,它不t 正确验证(字符太多,缺少内容等)rails returns 错误提示:

ArgumentError in MicropostsController#create First argument in form cannot contain nil or be empty

相关接口测试错误returns:

 FAIL["test_micropost_interface", MicropostsInterfaceTest, 2015-06-22 11:13:28 +0800]
 test_micropost_interface#MicropostsInterfaceTest (1434942808.57s)
        Expected at least 1 element matching "div#error_explanation", found 0..
        Expected 0 to be >= 1.
        test/integration/microposts_interface_test.rb:19:in `block in <class:MicropostsInterfaceTest>'

如何修复这些错误,以便用户友好的错误消息 (div#error_explanation) 能够正确显示?

支持信息

成员控制器:

class MembersController < ApplicationController
    before_filter :logged_in_user
  def index
    @micropost = current_user.microposts.build
    @feed_items = current_user.feed.paginate(page: params[:page])
  end
end

微型posts控制器:

class MicropostsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: :destroy

  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Micropost created!"
      # redirect_to root_url
      redirect_to members_path
    else
      @feed_items = []
      @micropost = []
      render 'members/index'
    end
  end

  def destroy
    @micropost.destroy
    flash[:success] = "Micropost deleted"
    # redirect_to request.referrer || root_url
    redirect_to request.referrer || members_path
  end

  private

    def micropost_params
      params.require(:micropost).permit(:content, :picture)
    end

    def correct_user
      @micropost = current_user.microposts.find_by(id: params[:id])
      # redirect_to root_url if @micropost.nil?
      redirect_to members_path if @micropost.nil?
    end
end

_micropost_form.html.erb

<%= form_for(@micropost, html: { multipart: true }) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_area :content, placeholder: "Compose new micropost (420 chars max)..." %>
  </div>
  <%= f.submit "Post", class: "btn btn-primary" %>
  <span class="picture">
    <%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>
  </span>
<% end %>

<script type="text/javascript">
  $('#micropost_picture').bind('change', function() {
    size_in_megabytes = this.files[0].size/1024/1024;
    if (size_in_megabytes > 5) {
      alert('Maximum file size is 5MB. Please choose a smaller file.');
    }
  });
</script>

app/models/micropost.rb

class Micropost < ActiveRecord::Base
  belongs_to :user
  default_scope -> { order(created_at: :desc) }
  mount_uploader :picture, PictureUploader
  validates :user_id, presence: true
  validates :content, presence: true, length: { maximum: 420 }
  validate  :picture_size

  private

    # Validates the size of an uploaded picture.
    def picture_size
      if picture.size > 5.megabytes
        errors.add(:picture, "should be less than 5MB")
      end
    end
end

更新

_error_messages.html.erb

<% if object.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      The form contains <%= pluralize(object.errors.count, "error") %>.
    </div>
    <ul>
    <% object.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
<% end %>

如果你看错误

First argument in form cannot contain nil or be empty

你可以清楚地看出,@micropost 变量的第一个参数是 nil。现在移动到控制器,看看你是否设置了那个变量。

在创建动作的 else 部分,在微博中 你有 @micoposts = [],一个空数组,然后传递给你的模板并导致错误。

修复:

将创建方法更改为:

def create
  @micropost = current_user.microposts.build(micropost_params)
  if @micropost.save
    flash[:success] = "Micropost created!"
    # redirect_to root_url
    redirect_to members_path
  else
    @feed_items = current_user.feed.paginate(page: params[:page])
    render 'members/index'
  end
end