【问题标题】:Use through option on a belongs_to ActiveRecord association在 belongs_to ActiveRecord 关联上使用 through 选项
【发布时间】:2012-12-06 17:54:00
【问题描述】:

有没有办法在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 的事情。使用最新的稳定 Rails(截至目前为 3.2.9)。

【问题讨论】:

  • @MrYoshiji - 在has_one 下,Rails 文档说:“只有在其他类包含外键时才应使用此方法。如果当前类包含外键,则应使用而是belongs_to。”
  • has_one 的文档还说“选项:[...] - :through 指定用于执行查询的连接模型。:class_name、:primary_key 和 :foreign_key 的选项是忽略,因为关联使用源反射。您只能通过连接模型上的 has_one 或 belongs_to 关联使用 :through 查询。"

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


【解决方案1】:

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 的选项是 忽略,因为关联使用源反射。你只能 通过 has_one 或 belongs_to 关联使用 :through 查询 连接模型。

他们在这里谈到了这个Rails has_one :through association

【讨论】:

  • 这似乎没有意义。 Lessonbelongs_to :lesson_group 存在是因为它确实有外键。同样LessonGroupbelongs_to :level 存在是因为它有外键。我会试试这个,但我不愿意依赖这种机制,即使它可以工作,因为文档并没有明确说明在这种情况下使用has_one
  • 我同意,这种情况还不清楚。这可能会让您感兴趣:stackoverflow.com/questions/2116017/…
  • belongs_to :through C 不存在,因为当前表不包含指向C 的外键。
【解决方案2】:

Rails 6Ruby 2.6 中,我遇到了类似的问题,我有一个User,它可能属于许多Organizations,但总是有一个primary_organization,这是第一个Organization。分配给。最初我是用方法设置的:

def primary_organization
  organizations.first
end

但是,这最终破坏了我的作用域链。上述primary_organization 方法可以重构为可链接的条件,而无需更改user.primary_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_user.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

organization.rb

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

has_many    :users,
              class_name:     'User',
              through:        :organization_users,
              inverse_of:     :organization_users,
              autosave:       true

【讨论】:

    猜你喜欢
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 2010-12-13
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    • 2011-09-28
    相关资源
    最近更新 更多