0

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 newsitemsid」は間違っているため、次のようになります。

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

このナットを割って開けてくれる人がいるといいのですが。

よろしくお願いします-PeterPiper

4

1 に答える 1

2

私も同じ問題を抱えていました。同様の例を書きます。

1.最初のモデル:

class Label < ActiveRecord::Base
 has_and_belongs_to_many :spaces
end

2. 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が間違ったテーブルを検索し、spaceslabelsではなくlabelsspacesを検索することがわかりました。これは、モデルの名前が原因だと思います。モデルを追加して解決しました。

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

これで、@space.labelsや@label.spacesなどのクエリを実行できるようになります。お役に立てば幸いです。

于 2012-04-08T11:33:34.113 に答える