Rails 3.1 HABTM ассоциация с custom_key генерирует неверный оператор соединения
Я столкнулся с довольно неприятной проблемой при попытке использовать ассоциации has_and_belongs_to_many.
Сценарий таков.
У меня есть продукт, с которым связано много новостей, и наоборот. Новостные статьи могут быть переведены на разные языки, поэтому для отслеживания новостей с одинаковым содержанием (но переведенных на другой язык) - я добавил news_id к новостям.
Моя проблема в том, что связь между продуктом и уникальными новостями (newsitem.news_id) отсутствует, а не в отдельном новостном сообщении (newsitem.id).
Мои модели:
class Product < ActiveRecord::Base
has_and_belongs_to_many :newsitems , :association_foreign_key => :news_id
end
class Newsitem < ActiveRecord::Base
has_and_belongs_to_many :products, :foreign_key => :news_id
end
Мои миграции следующие:
def change
create_table :products do |t|
t.string :name
t.timestamps
end
end
def change
create_table :newsitems do |t|
t.string :content
t.integer :news_id
t.integer :language_id
t.timestamps
end
end
def change
create_table :newsitems_products, :id => false do |t|
t.integer :news_id
t.integer :product_id
end
end
Используя эту настройку, я получаю следующий правильный sql при вызове:
news = Newsitem.first
news.products.to_sql
SQL:
"SELECT `products`.* FROM `products`
INNER JOIN `newsitems_products`
ON `products`.`id` = newsitems_products`.`product_id`
WHERE `newsitems_products`.`news_id` = 1"
Проблемы начинаются, когда я запрашиваю все новостные элементы, связанные с продуктом: prod = Products.first prod.newsitems.to_sql SQL:
"SELECT `newsitems`.* FROM `newsitems`
INNER JOIN `newsitems_products`
ON `newsitems`.`id` = `newsitems_products`.`news_id`
WHERE `newsitems_products`.`product_id` = 1"
Несмотря на то, что я объявил:association_foreign_key =>:news_id для продукта и:foreign_key =>:news_id для элемента новостей, генерировать "ON" newsitems
,id
"неправильно и должно быть:
ON `newsitems`.`news_id` = `newsitems_products`.`news_id`
Я надеюсь, что некоторые из вас могут открыть этот орех.
Заранее спасибо - Питер Пайпер
1 ответ
У меня была такая же проблема, напишу похожий пример.
1. Первая модель:
class Label < ActiveRecord::Base
has_and_belongs_to_many :spaces
end
2. Вторая модель:
class Space < ActiveRecord::Base
has_and_belongs_to_many :labels
end
3. Миграция:
rails g migration createSpacesLabels
Изменить миграцию:
class CreateSpacesLabels < ActiveRecord::Migration def up create_table :spaces_labels, :id => false do |t| t.references :space t.references :label end add_index :spaces_labels, [:label_id, :space_id] add_index :spaces_labels, [:space_id, :label_id] end def down drop_table :spaces_labels end end
Проблемы:
Я обнаружил, что рельсы ищут не ту таблицу, она ищет метки вместо пробелов, я думаю, это из-за названия моделей. Я решил это, добавив в модели:
has_and_belongs_to_many :labels,:join_table=>'spaces_labels' has_and_belongs_to_many :spaces,:join_table=>'spaces_labels'
Теперь вы должны иметь возможность выполнять запросы, такие как @space.labels или @label.spaces. Я надеюсь, что это помогает.