Похоже, вы не указали столбец opinionable_type:string
для своей модели мнения.
Попробуйте обновить миграцию следующим образом:
class CreateOpinions < ActiveRecord::Migration
def self.up
create_table :opinions do |t|
t.integer :opinionable_id
t.string :opinionable_type
# ... other fields
t.timestamps
end
end
def self.down
drop_table :opinions
end
end
Это решит ваш второй вопрос иOpinion.preload(:opinionable).all
должно работать хорошо.
Вы не можете выполнять объединения при полиморфной ассоциации, поскольку они могут находиться в разных таблицах, которые обнаруживаются после загрузки модели Opinion
.Именно поэтому для модели необходим столбец opinionable_type
.
Если вы попытаетесь это сделать, вы получите следующее исключение
ActiveRecord::EagerLoadPolymorphicError
: невозможно загружать полиморфную ассоциацию :opinionable
UPD: добавлено магическое соединение ^ _ ^
class Opinion < ActiveRecord::Base
belongs_to :opinionable, :polymorphic => true
belongs_to :opinionable_answer, :foreign_key => :opinionable_id, :class_name => "Answer"
scope :by_type, lambda { |type| joins("JOIN #{type.table_name} ON #{type.table_name}.id = #{Opinion.table_name}.opinionable_id AND #{Opinion.table_name}.opinionable_type = '#{type.to_s}'") }
end
Пример:
Opinion.by_type(Answer).to_sql
=> "SELECT \"opinions\".* FROM \"opinions\" JOIN answers ON answers.id = opinions.opinionable_id AND opinions.opinionable_type = 'Answer'"