ActiveRecord, found by polymorphic attribute

Having this:

class Event < ActiveRecord::Base belongs_to :historizable, :polymorphic => true end user = User.create! 

I can:

 Event.create!(:historizable => user) 

But I can not:

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

I should do this instead:

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

Update

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

+7
source share
3 answers

This was implemented in the Rails master and will be available in Rails 4. Thank you.

- @carlosantoniodasilva

+4
source

I'm doing it:

 user.events 

This is a valid AR request, you can relate it to other areas:

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

EDIT: AFAIK, on ​​the contrary, you must specify both fields (it makes sense: you can have a user with id 4 and one more thing with events, for example, Party, also with id 4).

EDIT2: Regarding “Why create and where ”: create at a higher level than where , because the former deals with the “full model” and the latter manages things to the database table level.

  • ActiveRecord create (AFAIK) uses a combination of new + update_param somewhere down the line.
  • update_param uses the xxxx= model methods to assign each individual property.
  • In your example, historizable= is the method created by belongs_to . Because belongs_to "knows" that it is polymorphic, it can deal with type and identifier.

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

 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 heard that this can change in Rails 4, and where can be more “intelligent”. But I have not checked yet.

0
source

Try:

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

All Articles