Ruby on Rails。如何在属于关系的Active Record中使用.build方法?


128

我无法在Rails中找到有关.build方法的任何文档(我目前正在使用2.0.2)。

通过实验,您似乎可以使用build方法has_many在保存任何一条记录之前将一条记录添加到关系中。

例如:

class Dog < ActiveRecord::Base
  has_many :tags
  belongs_to :person
end

class Person < ActiveRecord::Base
  has_many :dogs
end

# rails c
d = Dog.new
d.tags.build(:number => "123456")
d.save # => true

这将正确保存带有外键的狗和标签。这似乎在belongs_to关系中不起作用。

d = Dog.new
d.person.build # => nil object on nil.build

我也尝试过

d = Dog.new
d.person = Person.new
d.save # => true

Dog在这种情况下,未设置外键,这是因为在保存时,新人没有身份证,因为尚未保存。

我的问题是:

  1. 构建工作如何进行,以使Rails足够聪明地找出如何以正确的顺序保存记录?

  2. belongs_to恋爱关系中我该怎么做?

  3. 在哪里可以找到有关此方法的任何文档?

谢谢


关于文档,请参见《 Rails指南》中的“方法所添加的方法belongs_to“方法所添加的方法has_one。可以在API文档中找到更多技术文档:belongs_tohas_one
丹尼斯

Answers:


147

记录在哪里:

从API文档中“ 模块ActiveRecord :: Associations :: ClassMethods ”中has_many关联下

collection.build(attributes = {},…)返回一个或多个集合类型的新对象,这些对象已使用属性实例化并通过外键链接到该对象,但尚未保存。注意:仅当关联对象已存在时,此方法才有效,如果为nil,则无效!

向相反方向构建的答案是语法略有更改。以狗为例

Class Dog
   has_many :tags
   belongs_to :person
end

Class Person
  has_many :dogs
end

d = Dog.new
d.build_person(:attributes => "go", :here => "like normal")

甚至

t = Tag.new
t.build_dog(:name => "Rover", :breed => "Maltese")

您还可以使用create_dog使其立即保存(非常类似于您可以在集合上调用的相应“ create”方法)

导轨足够聪明吗?这很神奇(或者更准确地说,我不知道,很想找出答案!)


4
@BushyMark:它使用method_missing或metaporgramming来添加带有define_method的方法。
费德里科

@Federico缺少的方法在哪里定义?
12

1
@ alock27与ActiveRecord使用您find_by_emailfind_by_column_name方法所缺少的方法相同。它将您传递的方法转换为字符串并进行剖析,然后尝试将其与表的列名进行匹配。
bigpotato

@edmund感谢您的评论。明确地说,我了解method_missing的工作原理。我试图查找缺少定义此特定方法的文件的实际位置。
2013年

@ alock27如果您因为要研究其定义而询问,则应查看Metaprogramming Ruby。但是,如果您确实在寻找实际位置,则可以使用Google作为源代码。
MCB

48
@article = user.articles.build(:title => "MainTitle")
@article.save

>> d.tags.build(:number =>“ 123456”)>> d.save#=> true不一样吗?
antiqe
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.