has_many:通过has_and_belongs_to_many关联

Ras*_*eff 6 activerecord ruby-on-rails

我试图在Ruby on Rails项目中执行以下操作:

class FoodItem < ActiveRecord::Base
  has_and_belongs_to_many :food_categories
  has_many :places, :through => :food_categories
end

class FoodCategory < ActiveRecord::Base
  has_and_belongs_to_many :food_items
  belongs_to :place
end

class Place < ActiveRecord::Base  
  has_many :food_categories
  has_many :food_items, :through => :food_category
end
Run Code Online (Sandbox Code Playgroud)

但调用实例方法some_food_item.places会给我以下错误:

ActiveRecord::StatementInvalid: PGError: ERROR:  column 
food_categories.food_item_id does not exist
LINE 1: ...laces".id = "food_categories".place_id    WHERE (("food_cate...

: SELECT "places".* FROM "places"  INNER JOIN "food_categories" ON "places".id = "food_categories".place_id    WHERE (("food_categories".food_item_id = 1))
Run Code Online (Sandbox Code Playgroud)

这很有道理 - 因为FoodItem和FoodCategory上的HABTM我有一个名为的映射表food_categories_food_items.

我有什么做的就是some_food_item.places要正确对待地方了通过映射表,而不是寻找一个food_item_idfood_categories表?

Jai*_*yer 7

我的第一个答案版本不正确,但这个版本完美无缺.我第一次做了一些拼写错误(实际上没有创建应用程序进行测试的危险),但这次我验证了.并且需要一个插件,但这很容易.首先,安装插件:

script/plugin install git://github.com/ianwhite/nested_has_many_through.git
Run Code Online (Sandbox Code Playgroud)

这将安装Ian White的解决方法,并且无缝地工作.现在模型,直接从我设置的测试应用程序复制,以使其工作:

class FoodItem < ActiveRecord::Base
  has_many :food_category_items
  has_many :food_categories, :through => :food_category_items
  has_many :places, :through => :food_categories
end

class FoodCategory < ActiveRecord::Base
  has_many :food_category_items
  has_many :food_items, :through => :food_category_items
  belongs_to :place
end

class FoodCategoryItem < ActiveRecord::Base
  belongs_to :food_item
  belongs_to :food_category
end

class Place < ActiveRecord::Base
  has_many :food_categories
  has_many :food_category_items, :through => :food_categories
  has_many :food_items, :through => :food_category_items
end
Run Code Online (Sandbox Code Playgroud)

现在"远"协会的工作也一样. place_instance.food_items并且food_item.places两者都完美无缺,以及所涉及的简单协会.仅供参考,这是我的架构,以显示所有外键的位置:

create_table "food_categories", :force => true do |t|
  t.string   "name"
  t.integer  "place_id"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "food_category_items", :force => true do |t|
  t.string   "name"
  t.integer  "food_item_id"
  t.integer  "food_category_id"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "food_items", :force => true do |t|
  t.string   "name"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "places", :force => true do |t|
  t.string   "name"
  t.datetime "created_at"
  t.datetime "updated_at"
end
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

更新:这个问题最近出现了几次.我写了一篇文章,嵌套你的has_many:通过关系,详细解释.它甚至在GitHub上有一个附带的示例应用程序来下载和玩.