Ruby on rails 是否有一个动态生成的访问器
当在模型上声明一个Ruby on rails 是否有一个动态生成的访问器,ruby-on-rails,ruby,activerecord,model,has-one,Ruby On Rails,Ruby,Activerecord,Model,Has One,当在模型上声明一个有多个关系时,将动态添加一个访问器方法,允许传入一个ID数组: class Example < ActiveRecord::Base has_many :foos end 但是,当一个有一个关系被声明时,就会创建这样的访问器: class Example < ActiveRecord::Base has_one :foo end 为什么会出现这种差异? 为什么可以使用一个表单的ID设置多个关联,但要设置单个关联,需要一个嵌套表单,并且需要在模型上定义
有多个关系时,将动态添加一个访问器方法,允许传入一个ID数组:
class Example < ActiveRecord::Base
has_many :foos
end
但是,当一个有一个关系被声明时,就会创建这样的访问器:
class Example < ActiveRecord::Base
has_one :foo
end
为什么会出现这种差异?
为什么可以使用一个表单的ID设置多个关联,但要设置单个关联,需要一个嵌套表单,并且需要在模型上定义一个接受对于has\u one,您应该使用单数而不是复数:
has_one :foo
这是因为几乎没有关联宏创建“{{association\u name}}}}id”
accessor-它是由ActiveRecord
基于DB表中的列创建的。此外,has_one
association意味着关联的模型具有外键列,因此如果您的关联与DB schema一致,则不会产生错误:
foo = Foo.new
foo.example_id
对于动态生成的acessor,您应该使用模型中缺少的方法
为了具有动态关联模型,请使用polimirphic关联 为什么要为单个实例创建访问器?无需向其传递ID数组。访问器foo\u id=
相当于foo.id=
,那么为什么要创建它呢?根据,collection\u singular\u id=
(m.foo\u id=)方法通过适当的添加和删除,使集合只包含由提供的主键值标识的对象。这意味着它将把ID为[1,2,3]的foo分配给示例m
现在他们有了一个不同的方法collection=objects
(m.foo=),该方法将接收foo对象数组作为参数,并将这些foo与示例关联
最后,当我们使用has_one
关联时,只能有一个对象与示例关联。因此,我们不需要为同一工作使用两种不同的方法,因此它们没有collection\u singular\u id=
方法,因为这会造成混淆,但是它们有association=(associate)
方法来分配关联
从指南中:
association=方法将关联对象指定给此对象。在幕后,这意味着从该对象提取主键,并将关联对象的外键设置为相同的值
很抱歉在我的示例中,这是一个输入错误(现已修复)。问题仍然存在。为什么rails不生成一个foo\u id
accessor呢?那么只需使用m.foo.id
就可以了。产生差异的原因是,如果有很多,您需要迭代对象,所以方法\u id
是由ActiveRecord为此目的生成的。如果有一个
你不需要它。这不能回答我的问题。我对为什么感兴趣。这在嵌套形式中特别有趣。我可以设置foo\u id
而不必担心嵌套,但是对于has\u one
关系,我需要做不同的事情,使用嵌套表单以及接受嵌套的属性。这是正确的,但是在has\u many
关系中,情况是一样的:包含外键的多个,不是声明的模型有很多
,但是ActiveRecord
生成了一个foo\u id
访问器。@Pedr我认为这个foo\u id访问器不会生成,因为它可能会干扰从DB列生成的现有访问器。此外,我认为这可能会产生误导——它可能会产生一种假设,即这是外键。但生成的访问器将位于所属的模型上。具有多个
的模型没有foo\u id
列或访问器。@Pedr如果要建立“自”关联,则可能不是真的。这是真的。我没有考虑过。因此,这也许可以解释为什么它没有命名为foo\u id
,但在嵌套表单中,将单个资源与多个资源区别对待似乎仍然很奇怪。因为如果创建了它,您就不需要在希望设置a has\u one
关系的情况下嵌套表单。好的,我明白您的意思。好吧,因为已经有很多创建了一个ActiveRecord集合对象,所以它附带了几个方法(包括那些访问器)。但是,has_one
仅将一个模型与另一个模型关联,而没有为这些模型创建任何新方法,除了create_foo
等。如果您想要foo id
访问器,您必须在“示例”-模型中自己定义它。您说“我们不需要两种不同的方法来完成同一项工作”,但这两种方法是不同的,这就是我问题的全部要点。直接设置现有的单一关联涉及将模型实例传递到方法中。像example\u id这样的方法允许通过传递一个id来设置instance。这将使从表单设置单一关联变得更加容易,而不需要使用嵌套表单,接受
的\u嵌套属性。。我同意这一点。我不知道他们为什么没有这个方法,但是我们可以通过在模型中创建一个方法并在保存后将其添加到中来实现您想要的。
has_one :foo
foo = Foo.new
foo.example_id