Rails 3.1 HABTM ассоциация с custom_key генерирует неверный оператор соединения - PullRequest
0 голосов
/ 08 января 2012

Я столкнулся с довольно неприятной проблемой при попытке использовать ассоциации has_and_belongs_to_many.

Сценарий выглядит следующим образом.

У меня есть продукт, с которым связано много новостей, и наоборот.Новостные статьи могут быть переведены на разные языки, поэтому для отслеживания новостей с одинаковым содержанием (но переведенных на другой язык) - я добавил новостной идентификатор в новость.

Моя проблема в том, что ассоциациямежду продуктом и уникальной новостью (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 на newsitem для генерации«ON newsitems. id» неверно и должно быть:

ON `newsitems`.`news_id` = `newsitems_products`.`news_id`

Я надеюсь, что некоторые из вас могут открыть эту гайку.

Заранее спасибо - Питер Пайпер

1 Ответ

2 голосов
/ 08 апреля 2012

У меня была такая же проблема, напишу похожий пример.

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
  1. Редактировать миграцию:

    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
    
  2. Проблемы:

    Я обнаружил, что rails ищет неправильную таблицу , он ищет метки вместо пробелов, я думаю, это из-за названия моделей. Я решил это, добавив в модели:

    has_and_belongs_to_many :labels,:join_table=>'spaces_labels'
    
    has_and_belongs_to_many :spaces,:join_table=>'spaces_labels'
    

Теперь вы должны иметь возможность выполнять запросы, такие как @ space.labels или @ label.spaces. Надеюсь, это поможет.

...