6

有这个:

class Event < ActiveRecord::Base
  belongs_to :historizable, :polymorphic => 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

4

3 回答 3

3

这已在 Rails master 中实现,并将在 Rails 4 中可用。谢谢。

@carlosanoniodasilva

于 2013-02-08T17:15:06.420 回答
0

我这样做:

user.events

这是一个正确的 AR 查询,您可以将其与其他范围和内容链接起来:

user.events.where(<your event conditions here>)

编辑:反过来,AFAIK 必须指定两个字段(这是有道理的:您可以有一个具有 id 4 的用户和另一个具有事件的事物,例如派对,也具有 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子句时,那里的参数仅引用数据库字段。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(<your other queries here>)

我听说这可能会在 Rails 4 中改变,并且where可能更“智能”。但我还没有检查。

于 2013-02-07T17:54:33.840 回答
-2

尝试:

Event.joins(:historizable).where(:historizable => {:historizable_type => user})
于 2013-02-07T15:01:19.250 回答