移动 '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
遵循 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