Rails中有3个或更多模型关联混淆

时间:2012-09-28 15:54:51

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

我已经差不多一个星期了,因为我试图找到一个解决我的困惑的方法......这就是:

我有一个Program模型。 我有一个ProgramCategory模型。 我有一个ProgramSubcategory模型。

让我们说清楚一点:

ProgramCategory ======> Shows, Movies, 
ProgramSubcategory ===> Featured Shows, Action Movies
Program ==============> Lost, Dexter, Game of Thrones etc...

我希望能够将这些模型中的每一个与彼此联系起来。我有我想做的事情,尤其是多对多关联。我有一个categories_navigation JOIN模型/表,所有其他表都连接到它。通过这种方式,我可以访问所有这些模型的所有字段。

但是...

如您所知,has_many :through样式关联总是复数。没有像has_one:through或belongs_to一样的东西。但我想玩SINGULAR对象,而不是数组。 Program只有一个Subcategory,只有一个Category。我只是使用连接表来仅在那些之间建立连接3.例如,目前我可以访问program.program_categories[0].title,但我想访问它,例如program.program_category

我怎样才能拥有'has_many:通过能力但是还有一个单一的使用惯例? :|

P.S:我之前的问题也是关于这种情况,但我决定从头开始学习关联哲学。如果您愿意,可以在此处查看我之前的帖子:How to access associated model through another model in Rails?

1 个答案:

答案 0 :(得分:0)

为什么连接表与您有直接关系?最后,程序属于子类别,而子类别又属于一个类别。所以不需要连接表。

class Program < ActiveRecord::Base
  belongs_to :subcategory   # references the "subcategory_id" in the table
  # belongs_to :category, :through => :subcategory
  delegate :category, :to => :subcategory
end

class Subcategory < ActiveRecord::Base
  has_many :programs
  belongs_to :category    # references the "category_id" in the table
end

class Category < ActiveRecord::Base
  has_many :subcategories
  has_many :programs, :through => :subcategories
end

另一种观点是将类别设为树,因此您不需要“级别2”类别的其他模型,您可以添加所需的级别。如果您使用像“closure_tree”这样的树实现,您还可以获得所有子类别(在任何级别),所有超类别等

在这种情况下,您跳过子类别模型,因为它只是一个深度为2的类别

class Program < ActiveRecord::Base
  belongs_to :category   # references the "category_id" in the table

  scope :in_categories, lambda do |cats|
    where(:category_id => cats)  # accepts one or an array of either integers or Categories
  end
end

class Category < ActiveRecord::Base
  acts_as_tree
  has_many :programs
end

仅举例说明如何使用树按类别进行过滤。假设您有一个选择框,并从中选择一个类别。您想要检索与其任何子类别对应的所有对象,而不仅仅是类别。

class ProgramsController < ApplicationController

  def index

    @programs = Program.scoped
    if params[:category].present?
      category = Category.find(params[:category])
      @programs = @programs.in_categories(category.descendant_ids + [category.id])
    end

  end

end

树双赢!