3

有没有办法through在 belongs_to 关系中使用该选项?关于belongs_to的Rails 文档没有提到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)。

4

2 回答 2

5

在您提供的链接中:

指定与另一个类的一对一关联。仅当此类包含外键时才应使用此方法。

我认为您应该使用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

于 2012-12-06T17:57:46.353 回答
0

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

def primary_organization
  organizations.first
end

然而,这最终破坏了我的作用域链。上述primary_organization方法可以重构为可链接的条件,而无需更改user.primary_organization语法:

用户.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

组织用户.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

组织.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
于 2021-03-11T18:24:58.900 回答