更新(具体且更详细的先前版本如下):
我正在开发一个电视台网站。以下是我的计划部分的要求:
- 每个
程序
都有一个类别
。 - 每个
程序
都有一个子类别
。 - 每个
类别
都有许多子类别
- 每个
类别
都有许多程序
。 - 每个
子类别
都有一个类别
- 每个
子类别
都有许多程序
。
我想检索所有这三个要关联的模型。例如,我应该能够从我的 View 中检索以下数据:
同时:
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 > Program
这是我的代码:
程序类别模型:
has_many :programs
has_many :program_subcategories
程序子类别模型:
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
最佳答案
设计有点奇怪。如果您需要像
那样嵌套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
并且您不需要在 programs
中使用 program_category_id
外键,因为程序不是直接连接到类别,而是通过子类别连接。
更新
- Each Program has ONE Category.
- Each Program has ONE Subcategory.
- Each Category has MANY Subcategories
- Each Category has MANY Programs.
- Each Subcategory has ONE Category
- Each Subcategory has MANY Programs.
那么我相信我的答案仍然有效。您看,我的结构与您的描述相同,除了每个程序都有一个类别
(因为rails没有belongs_to through
)。你有一个
实际上是belongs_to
(因为它只能属于一个)。
但是一旦每个程序有一个子类别
并且每个子类别有一个类别
,程序的子类别的类别将是唯一的程序的类别。您可以通过在 Program 类上定义方法来拥有 p.program_category
:
def program_category
program_subcategory.program_category
end
现在是部分
I should be able to retrieve and also EDIT these:
p.program_category
假设您在电影类别的喜剧子类别中有一个节目。
您说您希望能够直接编辑程序类别(如果我理解正确的话),如下所示:
p.program_category = ProgramCategory.find_by_name("Sports")
那么您期望程序的子类别是什么?体育有很多子类别吗?您希望它是空白的吗?
因此,在此设计中,更改程序类别的唯一方法是更改程序的子类别:
p.program_subcategory = ProgramSubcategory.find_by_name("Tennis")
这样manke程序的类别==体育,因为网球属于体育。
注意:如果您有时确实想直接更改程序的类别,将其子类别留空,当然需要另一种设计。我不认为这很困难,但它需要更多的工作,而 Rails AR Associations 魔法的帮助却较少。
关于ruby-on-rails - 如何通过Rails中的另一个模型访问关联模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12608683/