如何通过Rails中的另一个模型访问关联模型?

更新(具体和更详细的以前版本如下):

我正在开发一个电视台网站。 以下是我的计划部分的要求:

  1. 每个Program都有一个Category
  2. 每个Program都有一个Subcategory
  3. 每个Category都有许多Subcategories
  4. 每个Category都有许多Programs
  5. 每个Subcategory都有一个Category
  6. 每个Subcategory都有许多Program

我想要检索所有这三个要关联的模型。 例如,我应该能够从我的视图中检索以下数据:

而:

 p = Program.find(1) p_cat = ProgramCategory.find(1) p_subcat = ProgramSubcategory.find(1) 

我应该能够检索并编辑这些:

 p.program_category p.program_subcategory 

要么

 program_category.programs program_subcategory.programs 

你可以看到我在下面尝试的内容来实现这些要求。 你可能会推荐我一种完全不同的方式或修复我的错误。

谢谢

================================================== ==========

我有3个型号。 他们应该互相嵌套。

ProgramCategory> ProgramSubcategory>程序

这是我的代码:

ProgramCategory模型:

  has_many :programs has_many :program_subcategories 

ProgramSubcategory模型:

 belongs_to :program_category has_many :programs 

程序模型:

 belongs_to :program_category belongs_to :program_subcategory 

当我创建一个新程序时,我可以设置它的类别,一切都很好。 我可以从双方访问它们。 例如,

 program.program_category 

给了我我的期望。 并且

 program_category.programs 

给了我想要的东西。

但是, 这是问题所在

当我尝试访问program.program_subcategory ,我只收到一个零。

虽然我的子类别的类别已设置且我的程序类别也已设置,但为什么我无法直接访问program.program_subcategory

当我输入program_category.program_subcategories ,我会收到该类别拥有的所有子类别。 但我不能直接从Program对象获取Subcategories。

我的计划如下。 任何帮助都是适当的。

 ActiveRecord::Schema.define(:version => 20120926181819) do create_table "program_categories", :force => true do |t| t.string "title" t.text "content" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false end create_table "program_subcategories", :force => true do |t| t.integer "program_category_id" t.string "title" t.text "content" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false end add_index "program_subcategories", ["program_category_id"], :name => "index_program_subcategories_on_program_category_id" create_table "programs", :force => true do |t| t.integer "program_category_id" t.integer "program_subcategory_id" t.string "title" t.text "content" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false end add_index "programs", ["program_category_id", "program_subcategory_id"], :name => "my_join1", :unique => true end 

设计很奇怪。 如果你需要像嵌套一样

 ProgramCategory > ProgramSubcategory > Program 

那么你需要

 class Program < ActiveRecord::Base belongs_to :program_subcategory end class ProgramSubcategory < ActiveRecord::Base belongs_to :program_category has_many :programs end class ProgramCategory < ActiveRecord::Base has_many :programs, :through => :program_subcategories has_many :program_subcategories end 

这样,当您创建程序时,您可以为其分配子类别。 此子类别已分配到类别,因此您可以通过program.program_subcategory.program_category访问它program.program_subcategory.program_category

而且programs不需要program_category_id外键,因为程序没有直接连接到类别,而是通过子类别。


UPDATE

  1. 每个计划都有一个类别。
  2. 每个程序都有一个子类别。
  3. 每个类别都有许多子类别
  4. 每个类别都有许多程序。
  5. 每个子类别都有一个类别
  6. 每个子类别都有许多程序。

然后我相信我的答案仍然有效。 你看,我的结构与你的描述相同,除了Each Program has ONE Category (因为rails没有belongs_to through )。 你has one实际上是belongs_to (因为它只能属于一个)。

但是, Each Program has ONE SubcategoryEach Subcategory has ONE Category程序的子类别的类别将是唯一的程序类别。 您可以通过在Program类上定义方法来获得p.program_category

 def program_category program_subcategory.program_category end 

现在是部分的

我应该能够检索并编辑这些:

p.program_category

想象一下,你有类别电影的子类别喜剧中的节目。

你说你希望能够直接编辑程序类别(如果我理解正确的话),像这样:

 p.program_category = ProgramCategory.find_by_name("Sports") 

但是你期望成为程序的子类别呢? 一旦体育有很多子类别? 你认为它是空白的吗?

因此,在此设计中,更改程序类别的唯一方法是更改​​程序的子类别:

 p.program_subcategory = ProgramSubcategory.find_by_name("Tennis") 

这将是manke计划的类别==体育,因为网球属于体育。

注意:如果您确实希望有时直接更改程序的类别,将其子类别留空,则需要另一种设计。 我不认为这是非常困难的,但它需要更多的工作,而Rails AR协会魔术的帮助较少。