在belongs_to ActiveRecord关联上使用through选项

时间:2012-12-06 17:54:00

标签: ruby-on-rails ruby-on-rails-3 activerecord ruby-on-rails-3.2 belongs-to

有没有办法在belongs_to关系中使用through选项? Rails documentation on belongs_to没有提及through作为选项,为什么不呢?我想做类似以下的事情:

class Lesson < ActiveRecord::Base
  attr_accessible :name, :lesson_group_id
  belongs_to :lesson_group
  belongs_to :level, through: :lesson_group
end

class LessonGroup < ActiveRecord::Base
  attr_accessible :name, :level_id
  belongs_to :level
  has_many :lessons
end

class Level < ActiveRecord::Base
  attr_accessible :number
  has_many :lesson_groups
end

然后我可以做Lesson.first.level之类的事情。使用最新的稳定Rai​​ls(截至目前为3.2.9)。

2 个答案:

答案 0 :(得分:4)

the link中你给了:

  

指定与另一个类的一对一关联。如果此类包含外键,则此方法仅应

我认为你应该使用has_one :level, through: :lesson_group,如下所示:

class Lesson < ActiveRecord::Base
  attr_accessible :name, :lesson_group_id
  belongs_to :lesson_group
  has_one :level, through: :lesson_group
end

class LessonGroup < ActiveRecord::Base
  attr_accessible :name, :level_id
  belongs_to :level
  has_many :lessons
end

class Level < ActiveRecord::Base
  attr_accessible :number
  has_many :lesson_groups
end

有关has_one的选项的文档的一部分:

  

:通过

     

指定用于执行查询的连接模型。选项:class_name,:primary_key和:foreign_key是   忽略,因为关联使用源反射。你只能   使用a:通过has_one或belongs_to关联查询   连接模型。

他们在这里讨论了Rails has_one :through association

答案 1 :(得分:0)

Rails 6Ruby 2.6 中,我遇到了类似的问题,我有一个 User,它可能属于许多 Organizations,但始终有一个 {{1} } 这是他们被分配到的第一个 primary_organization 。最初我是用这个方法设置的:

Organization

然而,这最终打破了我的作用域链。上面的 def primary_organization organizations.first end 方法可以重构为可链接的条件语句,而无需更改 primary_organization 语法:

user.rb

user.primary_organization

organization_user.rb

# has_many: OrganizationUsers > Organizations
# ==================================================================================
has_many    :organization_users,
              class_name:     'OrganizationUser',
              inverse_of:     :user,
              dependent:      :destroy,
              autosave:       true,

has_many    :organizations,
              class_name:     'Organization',
              through:        :organization_users,
              inverse_of:     :organization_users,
              source:         :organization

# *** ADDED IN REFACTOR ***
# has_one: Organization
# shortcut for:
#   • `user.organization_users.first.organization`
#   • `user.organizations.first`
# ==================================================================================
has_one     :primary_organization_user,
              -> {
                order(
                  created_at: :desc
                ).limit(1)
              },
              class_name:     'OrganizationUser',
              inverse_of:     :user

has_one     :primary_organization,
              class_name:     'Organization',
              through:        :primary_organization_user,
              inverse_of:     :organization_users,
              source:         :organization

organization.rb

# belongs_to: Organization
# ==================================================================================
belongs_to  :organization,
              class_name:     'Organization',
              inverse_of:     :organization_users

# belongs_to: User
# ==================================================================================
belongs_to  :user,
              class_name:     'User',
              inverse_of:     :organization_users