ActiveRecord, find by polymorphic attribute

故事扮演 提交于 2020-01-03 09:11:06

问题


Having this:

class Event < ActiveRecord::Base
  belongs_to :historizable, :polymorphic => true
end

user = User.create!

I can:

Event.create!(:historizable => user)

But I can't:

Event.where(:historizable => user)
# Mysql2::Error: Unknown column 'events.historizable' in 'where clause'

I have to do this instead:

Event.where(:historizable_id => user.id, :historizable_type => user.class.name)

Update

Code that reproduces the issue: https://gist.github.com/fguillen/4732177#file-polymorphic_where_test-rb


回答1:


This has been implemented in Rails master and will be available in Rails 4. Thanks.

– @carlosantoniodasilva




回答2:


I do this:

user.events

This is a proper AR query, you can chain it with other scopes and stuff:

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

EDIT: AFAIK the other way around you must specify both fields (makes sense: you could have a user with id 4 and another thing with events, like a Party, also with id 4).

EDIT2: Regarding "Why does create work and where doesn't": create is more highlevel than where, because the former deals with "a complete model", while the latter manages things at the database table level.

  1. ActiveRecord's create (AFAIK) uses a combination of new + update_param somewhere down the line.
  2. update_param uses your model's xxxx= methods for assigning each individual property.
  3. In your example, historizable= is a method built by the belongs_to expression. Since the belongs_to "knows" that it's polymorphic, it can deal with the type and id.

On the other hand, when you pass a hash to the where clause, the parameters there only refer to database fields. Rails provides scopes for "higher level" access:

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>)

I've heard that this might change in Rails 4, and where might be more "intelligent". But I have not checked yet.




回答3:


Try:

Event.joins(:historizable).where(:historizable => {:historizable_type => user})


来源:https://stackoverflow.com/questions/14753611/activerecord-find-by-polymorphic-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!