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更高层次,因为前者处理“完整模型”,而后者处理数据库表级别的事物。

  1. ActiveRecord的create (AFAIK)在某个地方使用了new + update_param的组合。
  2. update_param使用您的模型的xxxx=方法来分配每个属性。
  3. 在您的示例中, 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})