class CreateActivities < ActiveRecord::Migration
def change
create_table :activities do |t|
t.references :owner, polymorphic: true, index: true
t.string :action
t.text :parameters
t.timestamps null: false
end
end
end
class User < ActiveRecord::Base
has_many :activities, as: :owner, :source_type => "User", dependent: :nullify
...
end
class Activity < ActiveRecord::Base
belongs_to :owner, polymorphic: true
....
end
Chciałbym zbudować zapytanie typu
a = Activity.includes(:owner).order(:kolumna_z_tabeli_USER)
ale nie wychodzi mi to
Zapytanie :
a = Activity.includes(:owner)
jest OK, ale już
a = Activity.includes(:owner).references(:owner)
(bo chyba to references będzie mi potrzebne, by sortować po kolumnie z “ownera”) ciągle wywala mi błąd:
“ActiveRecord::EagerLoadPolymorphicError: Cannot eagerly load the polymorphic association :owner”
Jako że jest to asocjacja polimorficzna, nie da się zrobić zapytania sortowanego po kolumnie z ownera, bo nie wiadomo, do jakiej właściwie tabeli owner będzie należał. Rozwiązaniem jest po prostu sortowanie tego w Rubym.
To po co Ci wtedy polimorficzna asocjacja?
BTW source_type jest używane przy asocjacjach polimorficznych i has_many :through, czyli używanie tego tutaj jest niepotrzebne. Jeśli chcesz tylko te activities, które mają User jako owner_type, możesz zrobić coś takiego:
Activity.where(owner_type: 'User').joins('left outer join users on activities.owner_id = users.id').order('users.column ASC')
Uprzedzam, że taka konstrukcja nie działa niestety jako pre-load, więc jeśli chcesz zainicjować jeszcze te obiekty User, to musisz zrobić na tym scopie dodatkowo includes(:owner) (lub, bardziej zgodnie z prawdą, preload(:owner).
Dlatego że Activity.includes(:owner) jest równoważne Activity.preload(:owner) i nie robi joina (którego zrobić się nie da), tylko tyle zapytań, ile trzeba do wyciągnięcia rekordów i asocjacji. Natomiast jeśli robisz references(:owner), wymuszasz zrobienie konstrukcji Activity.eager_load(:owner), który próbuje zrobić left joina, a nie może go zrobić, bo asocjacja jest polimorficzna. Przeczytaj: