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

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

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

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

  1. 每个程序都有一个类别
  2. 每个程序都有一个子类别
  3. 每个类别都有许多子类别
  4. 每个类别都有许多程序
  5. 每个子类别都有一个类别
  6. 每个子类别都有许多程序

我想检索所有这三个要关联的模型。例如,我应该能够从我的 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 外键,因为程序不是直接连接到类别,而是通过子类别连接。


更新

  1. Each Program has ONE Category.
  2. Each Program has ONE Subcategory.
  3. Each Category has MANY Subcategories
  4. Each Category has MANY Programs.
  5. Each Subcategory has ONE Category
  6. 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/

相关文章:

ruby-on-rails - 如何将可安装引擎添加到 Rails 3.1 应用程序中?

ruby-on-rails - 在 has_many 关系中提取子对象的 id

ruby-on-rails - 如何删除 Sidekiq 预定作业?

ruby-on-rails - 为 heroku run rake、heroku run console 等关闭 NewRelic

html - 使用 Ruby 从登录可访问网页后 javascript 中提取值

ruby-on-rails - 在 Rails 中将图像存储为模型

ruby-on-rails - 无法使用 Devise、Rails 4 从 Omniauth 身份验证策略检索 access_token、refresh_token

ruby-on-rails - Mongoid store_in 产生随机结果

ruby-on-rails - 如何迭代多个数组并在每第 n 次迭代后添加异常?

Ruby 将参数传递给 block