我有两个类似的模型(简化):
RECIPE(has_one video)
视频(belongs_to食谱)
在RecipesController #new中,我渲染了一个用于创建资源的视图。 我使用form_for @recipe和所有常规f.helpers
问题是我需要一个字段来填充链接属性,这属于另一个对象(视频)。因此,由于f.helpers使用resource [field]作为前缀,我使用了常规的text_field_tag:link。
到目前为止,一切顺利。在RecipesController #create中我做: @recipe = Recipe.new(params[:recipe])
@recipe.video = Video.new(params[:link])
将视频分配给食谱。
在此之后我做了通常的@ recipe.save,这就是我被困住的地方。
我预计如果视频中包含任何错误,配方将不会保存,并且我将能够使用@ recipe.errors对象来获取所有错误(也来自视频中的错误)。
但不仅配方保存,@ recipe.errors不包含来自视频的消息。 我使用(部分“错误”,:object => @recipe)列出所有消息,但这不会获取视频对象触发的消息。
我尝试了各种各样的东西,例如,在部分内部我有一个最初检查的条件:
if object.errors.any?
object.errors.full_messages ...
end
我把它换成了:
if(object.errors.merge!(object.video.errors))。any? 但它没有悲伤地工作。
在这种情况下我该怎么办?如何在视频出错时阻止@recipe保存,以及如何将它们无缝地列在一起?
答案 0 :(得分:1)
处理嵌套对象需要一些工作,但并不难。从Rails 2.3开始,出现了“嵌套属性”和“嵌套对象形式”的概念(参见:http://guides.rubyonrails.org/2_3_release_notes.html#nested-attributes和http://guides.rubyonrails.org/2_3_release_notes.html#nested-object-forms)。
基本上,这可以让你做这样的事情:
<% form_for @recipe do |f| %>
<%= f.text_field :name %>
<%= f.text_field :description %>
<% f.fields_for :video do |v| %>
<%= v.text_field :link %>
<% end %>
<% end %>
如您所见,代码告诉表单在配方中有field_for:视频对象。然后您可以改变您的食谱:
class Recipe < ActiveRecord::Base
has_one :video
accepts_nested_attributes_for :video
end
此代码告诉ActiveRecord您可以使用配方传入视频对象的属性。所以现在,你所要做的就是。 。
Recipe.create(params[:recipe])
。 。 。它将创建配方和视频记录,因为您的表单包含视频信息,Recipe类接受_nested_attributes_for:video。
-
只是澄清一些关于代码的事情。你将params [:link]传递给Video.new。 Video.new不期望一个字符串,它期望一个属性的哈希。所以,你在打电话。 。
Video.new("example.com/video_file.mp4")
。 。 。当你真的想要传入时。
Video.new(:link => "example.com/video_file.mp4")
不是哈希,ActiveRecord不知道您尝试通过“新”设置哪个属性。你也可以这样做。 。
v = Video.new
v.link = params[:link]
。 。 。并设置该方式的属性。另外,根据控制器中的其他内容,您可能无法将recipe_id分配给视频,而您可能不会调用@ video.save。有时,ActiveRecord的酷感可以让它看起来好像不会发生这些事情 - 如果你使用的东西如accept_nested_attributes_for,你不需要做那些事情。但是,如果要手动执行此操作,则必须确保将它们全部保存,分配关联,检查两个对象是否存在错误以及管理事务。
-
关于这个的Rails文档并不错,并且经历了很多:http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
Ryan Daigle也有一篇很好的博客文章:http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes