我有一个帮助器,它实例化一个模型并呈现一个表单。此表单应该可用于应用程序中的任何视图
# support_form_helper
def support_form
@support_stats = SupportForm::Stat.find(get_stats_id)
@enquiry = SupportForm::Enquiry.new(stats_id: @support_stats.id)
render partial: 'support_form/enquiries/form'
end
它在视图中呈现:
# some_view.html.erb
<%= support_form %>
这是好的,直到我想提交表格并在控制器中验证它。
# enquiries_controller.rb
def create
@enquiry = SupportForm::Enquiry.new(params[:support_form_enquiry])
topic = @enquiry.topic
@stat = SupportForm::Stat.find(@enquiry.stats_id)
@stat.stats[topic] = @stat.stats[topic].to_i.next
respond_to do |format|
if @enquiry.valid? && @stat.save
format.html { redirect_to(root_path) }
else
format.html { redirect_to(:back) }
end
end
end
这是我无法使用附加到无效对象的错误渲染上一个视图的地方。再次调用帮助程序并初始化一个新的@enquiries
对象,显然没有错误。
如何在应用程序的多个视图中呈现表单,并且当对象无效时仍然返回带有对象的视图?
我找到了一个答案来回答我的问题,但这是个坏主意:
Render the action that initiated update
def创建 @enquiry = SupportForm :: Enquiry.new(params [:support_form_enquiry])
topic = @enquiry.topic
@stat = SupportForm::Stat.find(@enquiry.stats_id)
@stat.stats[topic] = @stat.stats[topic].to_i.next
if @enquiry.valid? && @stat.save
redirect_to(root_path)
else
render Rails.application.routes.recognize_path(request.referer).values.join("/")
end
end
问题是视图中可能存在提交表单的实例变量,我必须能够在应用程序中实例化所有实例变量然后.....不可能。
目前我正在考虑将错误放在flash哈希中......不是我想做的事情。返回原始对象后,我可以使用用户输入重新填充字段。
答案 0 :(得分:0)
使用redirect_to时,rails将启动一个全新的控制器&amp;查看序列。使用
渲染“path / to / template / from / view / folder”`
代替。
使用此模式的典型创建操作看起来像(在这种情况下为'post'对象):
def create
@post = Post.new(params[:post])
@created = @post.save
respond_to do |format|
if @created
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to post_path(@post) }
format.js
else
format.html { render :action => :new }
format.js
end
end
end
注意如果它成功创建我们如何完全重定向到帖子的“show”页面,但是如果它不成功我们只是做一个渲染。
您可能应该修改您的support_form帮助程序,以便它只创建一个新的@enquiry(如果尚未创建):
def support_form
@support_stats = SupportForm::Stat.find(get_stats_id)
@enquiry ||= SupportForm::Enquiry.new(stats_id: @support_stats.id)
render partial: 'support_form/enquiries/form'
end
|| =是“等于自己或”的简写。如果它尚未被定义(或者是nil或false),那么它将在or的第一部分失败并且传递到创建对象的第二部分。
在您的表单中,您还应该确保使用的是form_for,它将根据对象是否已经保存而提交给创建或更新操作。