更新(具体和更详细的先前版本如下):
我正在开发一个电视台网站。以下是我的计划部分的要求:
Program
都有一个Category
。Program
都有一个Subcategory
。Category
都有许多Subcategories
Category
都有许多Programs
。Subcategory
都有一个Category
Subcategory
都有许多Program
s。我想检索所有这三个要关联的模型。例如,我应该能够从我的视图中检索以下数据:
虽然:
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
对象获得子类别。
我的计划如下。任何帮助都是适当的。
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
答案 0 :(得分:2)
设计很奇怪。如果您需要嵌套
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_category_id
中不需要programs
个外键,因为程序没有直接连接到类,而是通过子类别。
<强>更新强>
- 每个程序都有一个类别。
- 每个程序都有一个子类别。
- 每个类别都有多个子类别
- 每个类别都有多个程序。
- 每个子类别都有一个类别
- 每个子类别都有多个程序。
醇>
然后我相信我的答案仍然有效。你知道,我的结构与你的描述相同,除了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 Associations魔术的帮助较少。