当我的模型包含与同一类型对象的两个关系时,我该如何构建它?

How do I construct my model when it contains two relations to the same type of object?

我正在使用 Rails 4.2.3 我有一个模型,它与同一类型的对象有两个关系,

class MyObject < ActiveRecord::Base
  belongs_to :user
  has_many :my_object_times
…
  has_one :my_object_time, foreign_key: :linked_my_object_time_id

我的数据库中 "has_one" 的列名是 "linked_my_object_time_id." 我想不通的是如何为链接对象编写模型。我知道我需要放两个“belongs_to”子句,但我不知道如何写第二个。到目前为止我有

class MyObjectTime < ActiveRecord::Base
  belongs_to :my_object

当我去保存我的对象时……

    my_object.linked_my_object_time = my_object_time
    my_object.save

我收到错误“NoMethodError(未定义方法 `linked_my_object_time=' for #”

创建关联时也可以这样创建

rails generate model MyObject => parent

rails g model MyObjectTime my_object:references => child

并在 my_object.rb

class MyObject < ActiveRecord::Base
  has_one :my_object_time
end

然后你可以像这样从 my_object_次引用 my_object

my_object_time.my_object

Rails 根据关联名称神奇地推断出关联的外键及其模型名称。如果外键或模型名称与关联名称不同,您必须明确告诉 rails 要使用哪个 class 名称和外键。这样做将允许您使用两个关系编写模型。

它应该看起来像这样:

class MyObject < ActiveRecord::Base
  belongs_to :user
  has_many :my_object_times
  has_one :linked_my_object_time, class_name: 'MyObjectTime'

这里发生了什么?我更改了 has_one 关联的名称,因为它需要在名称上与 rails 将推断出的 has_many 关系区分开来。此文件中没有名称冲突,但如果您使用 has_many :my_object_times 和 has_one :my_object_time,您将无法区分关联(即. belongs_to :my_object) 在 MyObjectTime 模型中。因为我更改了关联名称,rails 无法再推断模型名称,所以我指定它。但是因为rails一般会在关联名中加上_id,所以应该可以从关联名推断出linked_my_object_time_id的外键列。

MyObjectTime 模型怎么样?

class MyObjectTime < ActiveRecord::Base
  belongs_to :my_object
  belongs_to :whatever_you_want_to_call_it, class_name: 'MyObject', foreign_key: 'linked_my_object_time_id'

第一个 belongs_to 是 has_many 的反向关联:my_object_times 和 rails 将在 MyObjectTime table 正如预期的那样。第二个 belongs_to 必须有一个不同的关联名称才能区分关联,并且由于关联名称已更改,我必须包括 class 名称和 foreign_key 因为它无法从协会名称推断。

我的所有信息都来自 here

(编辑:关联中的固定语法)