2

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

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

  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 个模型。它们应该嵌套在彼此中。

程序类别 > 程序子类别 > 程序

这是我的代码:

程序类别模型:

 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
4

1 回答 1

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因为程序不是直接连接到类别,而是通过子类别。


更新

  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节目的子类别的类别将是唯一节目的类别。您可以p.program_category通过在 Program 类上定义方法来获得:

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 的魔法帮助更少。

于 2012-09-26T20:08:39.113 回答