简体   繁体   English

Rails has_one与多态关联

[英]Rails has_one with polymorphic Association

I'm having a problem when I try to access relationships or attributes of my models. 尝试访问模型的关系或属性时遇到问题。 I have the following code: 我有以下代码:

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

A user can have multiple occupations and these occupations have specific relationships and attributes. 一个用户可以有多个职业,这些职业具有特定的关系和属性。

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

The problem occurs in the Parent classes. 该问题发生在Parent类中。 A parent can have multiple children, but how can I access these children? 一位父母可以有多个孩子,但是我该如何访问这些孩子?

I tried the following but unsuccessfully: 我尝试了以下操作,但未成功:

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 (undefined method `children' for Occupation::ActiveRecord_AssociationRelation:0x0000559d4c601898 NoMethodError(用于Occupation :: ActiveRecord_AssociationRelation:0x0000559d4c601898的未定义方法`children'

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

As indicated by the error, returns an ActiveRecord_AssociationRelation which does not have the method children . 正如错误指示,返回ActiveRecord_AssociationRelation不具有法children

If you do: 如果您这样做:

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

That will return a single occupation record. 那将返回一个occupation记录。 But, you don't want the occupation , you want the Parent . 但是,您不想要occupation ,您想要Parent So, try: 因此,请尝试:

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

But, if that user doesn't have an occupation with occupation_type "Parent", then you're going to get some errors (because you'll try to call occupationable on a nil object). 但是,如果该user不具有occupation为“父母”的occupation_type ,那么您将得到一些错误(因为您将尝试在nil对象上调用occupationable )。

So, you could try: 因此,您可以尝试:

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

I don't know where you're using that code. 我不知道您在哪里使用该代码。 But wherever it is, you need to know a lot about how your models are set up. 但是无论身在何处,您都需要了解很多有关如何设置模型的知识。 You might consider going for some encapsulation. 您可能会考虑进行封装。 Something, perhaps, like: 可能是这样的:

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

In which case you could do something like: 在这种情况下,您可以执行以下操作:

User.find(1).children

And now you don't need to know anything about how your models are set up in order to find the children. 现在,您无需了解如何设置模型就能找到孩子。

Down the road, I imagine you might end up doing something like: 在路上,我想您可能最终会做类似的事情:

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

In which case, you might do: 在这种情况下,您可以这样做:

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

You're going to end up with redundancy (maybe a lot). 您将最终获得冗余(也许很多)。 And, it might get tricky when you go to find all the Teachers for a Student or Parents for a Child . 而且,当您找到所有StudentTeachersChild Parents时,可能会变得很棘手。 But, that's a whole other kettle of fish. 但是,那是另外一锅鱼。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM