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

时间:2012-09-26 19:05:46

标签: ruby-on-rails ruby ruby-on-rails-3

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

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

  1. 每个Program都有一个Category
  2. 每个Program都有一个Subcategory
  3. 每个Category都有许多Subcategories
  4. 每个Category都有许多Programs
  5. 每个Subcategory都有一个Category
  6. 每个Subcategory都有许多Program s。
  7. 我想检索所有这三个要关联的模型。例如,我应该能够从我的视图中检索以下数据:

    虽然:

    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
    

1 个答案:

答案 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个外键,因为程序没有直接连接到,而是通过子类别。


<强>更新

  
      
  1. 每个程序都有一个类别。
  2.   
  3. 每个程序都有一个子类别。
  4.   
  5. 每个类别都有多个子类别
  6.   
  7. 每个类别都有多个程序。
  8.   
  9. 每个子类别都有一个类别
  10.   
  11. 每个子类别都有多个程序。
  12.   

然后我相信我的答案仍然有效。你知道,我的结构与你的描述相同,除了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 Associations魔术的帮助较少。