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 并且在 newsitem 上声明了 :foreign_key => :news_id ,但生成“ON newsitems. id”是错误的,应该是:

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

我希望你们中的一些人能破解这个坚果。

在此先感谢 - 彼得派珀

4

1 回答 1

2

我有同样的问题,我会写一个类似的例子。

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 之类的查询了。我希望它有所帮助。

于 2012-04-08T11:33:34.113 回答