【问题标题】:3 or more model association confusion at RailsRails 3 个或更多模型关联混淆
【发布时间】:2012-09-28 15:54:50
【问题描述】:

自从我试图找到解决我的困惑的方法以来已经快一个星期了......这里是:

我有一个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 through 之类的东西。但我想玩 SINGULAR 对象,而不是数组。一个Program 只有一个Subcategory 和一个Category。我只是使用连接表来仅在这 3 个之间建立连接。例如,目前我可以访问 program.program_categories[0].title,但我想访问它,例如 program.program_category

我怎样才能同时拥有 'has_many :through 的能力和 has_one 的单数用法约定? :|

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

【问题讨论】:

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


    【解决方案1】:

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

    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”之类的树实现,您还可以获得所有子类别(在任何级别)、所有超类别等

    在这种情况下,您会跳过 Subcategory 模型,因为它只是一个 depth=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
    

    树赢!

    【讨论】:

    • 不...当我尝试访问 program.program_category 时出现此错误:NoMethodError: undefined method...顺便说一句,您的第二个建议是有道理的。事实上,我只是在寻找能给我想要的东西的东西。不管它是什么。你能推荐一些关于那棵树的资源吗?
    • 它应该是 program.category,而不是 program.program_category.... 抱歉,我给的课程名称与预期不同。
    • 我最近推荐(并使用)github.com/mceachen/closure_tree,即使设置起来不简单,也必须手动编写迁移,它提供了很多功能和速度。
    • 不.. 我已经根据我的情况采纳了你的联想。所以就我而言,这就是program_category。因为:delegate :program_category, :to =&gt; :program_subcategory。它真的很奇怪。这不应该这么难得到。我想要的只是使用单数而不是复数 - 等等数组。
    • 我真的很害怕这个类别的东西。我想我会通过建立一个类别系统。我期待 Rails 和 ActiveRecord 可以非常轻松地添加 has_one 和 belongs_to 行……我想我必须更加努力才能在 Rails 获得一些能力。谢谢你的帮助。虽然我还没说完,但我会接受你的回答。您提供的信息可能对某些人有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多