0

Я пытаюсь аппроксимировать полиморфные отношения в Rails 3 с ассоциацией has-and-to-many-many (HABTM).Rails 3 HABTM - объект пересечения доступа

Таблица пересечения (user_favorites) имеет следующие поля: user_id, favorite_id, favorite_class

В классе пользователя, у меня есть отношения, определенные:

has_and_belongs_to_many :favorite_users, :class_name => "User", :join_table => "user_favorites", :association_foreign_key => "favorite_id", :foreign_key => "user_id", :conditions => "user_favorites.favorite_class='User'" 

Для получения данных, это работает, как ожидалось. К сожалению, это определение не добавит значения favorite_class, которые мне нужны («Пользователь» в этой ситуации).

Есть ли способ, возможно, используя Arel, установить поле favorite_class в нужное значение до сохранения записи?

ответ

0

Я был в состоянии решить эту проблему с помощью: insert_sql вариант (используйте примечание отдельных цитат):

:insert_sql => 'INSERT INTO user_favorites (user_id, favorite_id, favorite_type) VALUES (#{id}, #{record.id}, "User")' 
+0

Не вниз, но я рекомендую против этого. Рельсы зависят от следующих соглашений. выполнение sql-вставок, подобных этому, - это подход PHP, который не рекомендуется для профессионального кода производства. –

2

A has_many через ассоциацию может работать лучше. Вот статья, которая может помочь. Он объясняет проблему полиморфным has_many: через отношения и предлагает обходной путь.

http://blog.hasmanythrough.com/2006/4/3/polymorphic-through

это может быть полезно также:

Polymorphic habtm relationships with Rails/ActiveRecord

+0

Спасибо за ответ. – craig

+0

+1 habtm не допускает дополнительных полей для объединения соединений. Его часто называют устаревшим, потому что изменение ассоциаций (от habtm до hmt) и кода, который их использует, - это боль в первый раз, когда требуется дополнительное поле. has_many: через позволяет это без этих основных модов. –

0

У вас есть SQL-инъекция в вашем варианте. Лучше использовать в вашей модели UserFavourites следующее:

before_save :set_favourite_type 

private 

def set_favorite_type 
    self[:favorite_type] = self.favoritable.class.to_s 
end 

или, по крайней мере, использование параметризованных запросов вместо # {}