从具有多态关联的一张表中检索行
我有一个模型与其他三个表具有多态关联:
class User < ActiveRecord::Base
belongs_to :authenticatable, :polymorphic => true
# == Schema Information
#
# Table name: employees
#
# id :integer(4) not null, primary key
# ...
# school_id :integer(4)
class Guardian < ActiveRecord::Base
has_one :user, :as => :authenticatable
belongs_to :school
# == Schema Information
#
# Table name: guardians
#
# id :integer(4) not null, primary key
# ...
# school_id :integer(4)
class Guardian < ActiveRecord::Base
has_one :user, :as => :authenticatable
belongs_to :school
# == Schema Information
#
# Table name: students
#
# id :integer(4) not null, primary key
# ...
# school_id :integer(4)
class Student < ActiveRecord::Base
has_one :user, :as => :authenticatable
belongs_to :school
如您所见,最后 3 个模型属于“学校”模型,因此有一个名为 school_id
的列。我想从 user
检索所有行,以便它们相应的可验证 school_id 等于某个值。为了澄清,我想做这样的事情:
User.joins(:authenticatable).where(:school_id => some_value)
事实上,这将导致
ActiveRecord::EagerLoadPolymorphicError
最后的说明,我设法查找一些文档,这些文档表明在多态关联上使用 include 应该有效,例如:
User.find(:all, :include => :authenticatable) (This works)
但是如果我这样做:
User.find(:all, :include => :authenticatable).where(:school_id => some_value)
它会破坏轨道,因为 User.find(...)
返回一个 Array
并且没有为该类定义 where 方法。
我尝试过其他一些选择,但没有找到实现我想要的方法。你能帮助我吗?谢谢!
I have one model which has a polymorphic association with three other tables:
class User < ActiveRecord::Base
belongs_to :authenticatable, :polymorphic => true
# == Schema Information
#
# Table name: employees
#
# id :integer(4) not null, primary key
# ...
# school_id :integer(4)
class Guardian < ActiveRecord::Base
has_one :user, :as => :authenticatable
belongs_to :school
# == Schema Information
#
# Table name: guardians
#
# id :integer(4) not null, primary key
# ...
# school_id :integer(4)
class Guardian < ActiveRecord::Base
has_one :user, :as => :authenticatable
belongs_to :school
# == Schema Information
#
# Table name: students
#
# id :integer(4) not null, primary key
# ...
# school_id :integer(4)
class Student < ActiveRecord::Base
has_one :user, :as => :authenticatable
belongs_to :school
As you can see, the last 3 models belong to a "school" model and therefore have a column named school_id
. I want to retrieve all rows from user
such that their corresponding authenticatable school_id is equal to some value. To clarify, I'd like to do something like this:
User.joins(:authenticatable).where(:school_id => some_value)
As it is, that will result in an
ActiveRecord::EagerLoadPolymorphicError
on a final note, i managed to look up some documentation which suggests that using include on a polymorphic association should work, such as:
User.find(:all, :include => :authenticatable) (This works)
However if I do this:
User.find(:all, :include => :authenticatable).where(:school_id => some_value)
It breaks rails, because User.find(...)
returns an Array
and the where method is not defined for that class.
I've tried some other options and have not found a way to accomplish what I want. Can you help me? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以尝试通过在
joins
语句中使用SQL查询来解决它:我实际上没有尝试它,但是多态关联。向模型添加 2 列:
xxx_type
和xxx_id
。他们负责处理关联。具有多种型号。You can try to solve it by using SQL query in
joins
statement:I not actually try it, but polimorphic assoc. adds 2 columns to model:
xxx_type
andxxx_id
. They serve to handle assoc. with multiple models.您可以使用子查询进行操作,也许可以得到一些工作:
如果您使用的是 Rails 5,他们将
.or
添加到ActiveRecord
,因此您可能能够加入有些组合在一起,例如:merge
是另一种可能会产生一些结果的方法:我不太熟悉跨多态表的查询,因此您的情况可能与上述方法有所不同。最坏的情况是,您可能最终不得不执行多个查询来保留范围:
您现在可能会陷入模式困境,但如果您可以自由地更改它,那么看起来您可能会更好地使用单个查询-表继承关系:
然后你只需说:
我发现多态关系在很多情况下比它们的价值更麻烦,因为执行查询和批量更新等操作非常困难,并且使得不可能使用外键约束。经过一些额外的思考,通常会有一个合理的数据模型在没有它们的情况下也能很好地工作。
You could futz around with sub-queries and maybe get something working:
If you're using Rails 5, they added
.or
toActiveRecord
, so you might be able to join some together like:merge
is another method that might yield some results:I'm not too familiar with querying across polymorphic tables, so your mileage may vary with the above. Worst case, you may end up having to do more than one query to preserve the scope:
You may be stuck with the schema now, but if you're at liberty to change it, it looks like you might be better off with a single-table inheritance relationship:
Then you simply say:
I've found polymorphic relations to be more trouble than they're worth in many cases due to how difficult it is to do things like queries and bulk updates, as well as making it impossible to use foreign key constraints. With some extra thought, there's usually a reasonable data model that works well without them.