[英]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
. 而且,当您找到所有Student
的Teachers
或Child
Parents
时,可能会变得很棘手。 But, that's a whole other kettle of fish. 但是,那是另外一锅鱼。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.