我试图做一个Ruby on Rails项目如下:
I am trying to do the following in a Ruby on Rails project:
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
但调用实例方法some_food_item.places使我有以下错误:
But calling the instance method some_food_item.places gives me the following error:
的ActiveRecord :: StatementInvalid:PGError:错误:列food_categories.food_item_id不存在
线路1:...鞋带.ID =food_categories.place_id WHERE((food_cate ...
ActiveRecord::StatementInvalid: PGError: ERROR: column food_categories.food_item_id does not exist
LINE 1: ...laces".id = "food_categories".place_id WHERE (("food_cate...
:选择地方*从地方INNER JOINfood_categoriesON位.ID =food_categories.place_id WHERE((food_categories.food_item_id = 1))
: SELECT "places".* FROM "places" INNER JOIN "food_categories" ON "places".id = "food_categories".place_id WHERE (("food_categories".food_item_id = 1))
这是非常合情合理的 - 因为FoodItem和FoodCategory的HABTMs我有映射表名为food_categories_food_items
Which makes perfect sense - because of the HABTMs on FoodItem and FoodCategory I have the mapping table named food_categories_food_items.
我有什么做的就是some_food_item.places通过映射表看,而不是寻找的food_categories表food_item_id地方是否正确?
What do I have to do to get some_food_item.places to look places up correctly through the mapping table instead of looking for a food_item_id in the food_categories table?
在回答我的第一个版本是不正确的,但是这一次完美的作品。我做了几个错别字的第一次,但这次我验证(不是实际创建一个应用程序来测试这一危险)。和一个插件是必要的,但是这是容易的。首先,安装插件:
My first version of the answer was incorrect, but this one works perfectly. I made a couple of typos the first time (the hazard of not actually creating an app to test) but this time I verified. And a plugin is needed, but this is easy. first, install the plugin:
script/plugin install git://github.com/ianwhite/nested_has_many_through.git
本安装伊恩·怀特的解决办法,它可以无缝地。现在的机型,直接从测试应用程序,我设置复制到得到这个工作:
This installs Ian White's workaround, and it works seamlessly. Now the models, copied directly from the test app I setup to get this working:
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
现在远协会工作也很好。 place_instance.food_items
和 food_item.places
两者完美的工作,以及所涉及的简单关联。仅供参考,这里是我的架构展现,所有的外键进入:
Now "far" associations work just as well. place_instance.food_items
and food_item.places
both work flawlessly, as well as the simpler associations involved. Just for reference, here's my schema to show where all the foreign keys go:
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
希望这有助于!
Hope this helps!
更新:这个问题已经拿出了几次最近。我写了一篇文章,nesting你的has_many:通过关系中详细讲解。它甚至有GitHub上的随附示例应用程序下载和玩。
UPDATE: This question has come up a few times recently. I wrote an article, nesting your has_many :through relationships, to explain in detail. It even has an accompanying example application on GitHub to download and play around with.