ActiveRecord,通过多态属性查找
有这个:
class Event true end user = User.create!
我可以:
Event.create!(:historizable => user)
但我不能:
Event.where(:historizable => user) # Mysql2::Error: Unknown column 'events.historizable' in 'where clause'
我必须这样做:
Event.where(:historizable_id => user.id, :historizable_type => user.class.name)
更新
重现问题的代码: https : //gist.github.com/fguillen/4732177#file-polymorphic_where_test-rb
这已在Rails master中实现,并将在Rails 4中提供。谢谢。
– @carlosantoniodasilva
我这样做:
user.events
这是一个正确的AR查询,您可以将其与其他范围和内容链接:
user.events.where()
编辑:AFAIK反过来你必须指定两个字段(有意义:你可以有一个id为4的用户和另一个有事件的东西,比如Party,也有id 4)。
EDIT2:关于“为什么create
工作而不where
”: create
比其他where
更高层次,因为前者处理“完整模型”,而后者处理数据库表级别的事物。
- ActiveRecord的
create
(AFAIK)在某个地方使用了new
+update_param
的组合。 -
update_param
使用您的模型的xxxx=
方法来分配每个属性。 - 在您的示例中,
historizable=
是由belongs_to
表达式构建的方法。 由于belongs_to
“知道”它是多态的,它可以处理类型和id。
另一方面,当您将哈希传递给where
子句时, where
的参数仅引用数据库字段 。 Rails提供“更高级别”访问的范围:
class Event < ActiveRecord::Base ... scope :by_historizable, lambda { |h| where(:historizable_id => h.id, :historizable_type => h.class.name) } end ... Event.by_historizable(user).where()
我听说这可能会在Rails 4中发生变化,而且可能更加“智能”。 但我还没有检查过。
尝试:
Event.joins(:historizable).where(:historizable => {:historizable_type => user})