Rails has_one与多态关联

时间:2018-07-26 14:20:40

标签: ruby-on-rails

当我尝试访问模型的关系或属性时遇到问题。我有以下代码:

class Occupation < ApplicationRecord
  belongs_to :user
  belongs_to :occupationable, polymorphic: true
end

用户可以有多个职业,这些职业具有特定的关系和属性。

class User < ApplicationRecord
  has_many :occupations, dependent: :destroy
end

class Teacher < ApplicationRecord
  has_one :occupation, as: :occupationable
end

class Psychologist < ApplicationRecord
 has_one :occupation, as: :occupationable
end

class Parent < ApplicationRecord
  has_one :occupation, as: :occupationable
  has_many :children
end

该问题发生在Parent类中。父母可以有多个孩子,但是我该如何访问这些孩子?

我尝试了以下操作,但未成功:

ID | OCCUPATIONABLE_ID | OCCUPATIONABLE_TYPE | USER_ID | CREATED_AT              | UPDATED_AT              
---|-------------------|---------------------|---------|-------------------------|-------------------------
1  | 1                 | Parent              | 1       | 2018-07-26 13:49:06     | 2018-07-26 13:49:06           


User.find(1).occupations.where(occupationable_type: "Parent").children
  

NoMethodError(未定义的方法“ children”用于   职业:: ActiveRecord_AssociationRelation:0x0000559d4c601898

1 个答案:

答案 0 :(得分:1)

User.find(1).occupations.where(occupationable_type: "Parent").children

如错误所示,返回不具有方法ActiveRecord_AssociationRelation的{​​{1}}。

如果您这样做:

children

这将返回单个User.find(1).occupations.find_by(occupationable_type: "Parent") 记录。但是,您不需要occupation,而是想要occupation。因此,尝试:

Parent

但是,如果User. find(1). occupations. find_by(occupationable_type: "Parent"). occupationable. children 的{​​{1}}中没有user“父母”,那么您会遇到一些错误(因为您将尝试调用{ occupation对象上的{1}}。

因此,您可以尝试:

occupation_type

我不知道您在哪里使用该代码。但是无论身在何处,您都需要了解很多有关如何设置模型的知识。您可能会考虑进行封装。也许是这样的:

occupationable

在这种情况下,您可以执行以下操作:

nil

现在,您无需了解有关如何设置模型来查找子代的任何信息。

在路上,我想您可能最终会做类似的事情:

User.
  find(1).
  occupations.
  find_by(occupationable_type: "Parent")&.
  occupationable&.
  children

在这种情况下,您可以这样做:

class User < ApplicationRecord
  has_many :occupations, dependent: :destroy

  def occupation(type)
    occupations.
    find_by(occupationable_type: type)&.
    occupationable
  end

  def children
    occupation('Parent')&.children
  end

end

最终将导致冗余(也许很多)。而且,当您找到User.find(1).children 的所有class Teacher < ApplicationRecord has_one :occupation, as: :occupationable has_many :students end class User < ApplicationRecord has_many :occupations, dependent: :destroy def occupation(type) occupations. find_by(occupationable_type: type)&. occupationable end def children occupation('Parent')&.children end def students occupation('Teacher')&.students end end 的{​​{1}}时,可能会变得很棘手。但是,那是另外一锅鱼。