如何通过Rails中的另一个模型访问关联模型?
更新(具体和更详细的以前版本如下):
我正在开发一个电视台网站。 以下是我的计划部分的要求:
- 每个
Program
都有一个Category
。 - 每个
Program
都有一个Subcategory
。 - 每个
Category
都有许多Subcategories
- 每个
Category
都有许多Programs
。 - 每个
Subcategory
都有一个Category
- 每个
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
- 每个计划都有一个类别。
- 每个程序都有一个子类别。
- 每个类别都有许多子类别
- 每个类别都有许多程序。
- 每个子类别都有一个类别
- 每个子类别都有许多程序。
然后我相信我的答案仍然有效。 你看,我的结构与你的描述相同,除了Each Program has ONE Category
(因为rails没有belongs_to through
)。 你has one
实际上是belongs_to
(因为它只能属于一个)。
但是, Each Program has ONE Subcategory
, Each 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协会魔术的帮助较少。