【问题标题】:Rails has_many with direct and indirect associationRails has_many 具有直接和间接关联
【发布时间】:2016-01-05 02:58:09
【问题描述】:

我有三个模型:Category、Line 和 Product。

类别有线条。
线有产品。
并且产品也可以直接属于Category。

所以我有两个关联变体:

1 - Category -> Line -> Product
2 - Category -> Product

如何使用has_many 来实现这个?

当然,我不能像这样声明两个has_many

# category.rb
has_many :lines
has_many :products, through: :lines
has_many :products

【问题讨论】:

  • 如果产品可以直接属于类别,为什么不尝试has_many :lineshas_many :products之类的?
  • @Kiloreux 因为我也想通过线路访问产品

标签: ruby-on-rails ruby activerecord database-design


【解决方案1】:

你应该这样设置它:

has_many :lines
has_many :line_products, through: lines, source: products
has_many :products

通过:source,我们告诉Rails 在Line 模型上寻找一个名为:products 的关联并使用它。

您也可以查看http://guides.rubyonrails.org/association_basics.html#has-many-association-reference 了解更多信息。

【讨论】:

  • 我想保留一个独特的界面来访问产品。最后,我将所有产品直接与类别相关联。
  • 并且与行的关联是可选的。
【解决方案2】:

我假设我们正在尝试构建一个看起来像这样的查询:

SELECT * FROM products
  LEFT OUTER JOIN lines ON products.line_id = lines.id
  WHERE lines.category_id = <category_id> 
    OR products.category_id = <category_id>;

Category 中,我们可以创建一个实例方法而不是使用关联:

class Category < ActiveRecord::Base
  def products
     Product.eager_load(:line)
      .where("products.category_id = :id OR lines.category_id = :id", {id: id})
  end
end

但如果关联真的是你的事,这样的事情可能会奏效(我不是 100% 确定):

class Category < ActiveRecord::Base
  has_many :products, ->(category) { 
    reset.eager_load(:line)
      .where("products.category_id = :id OR lines.category_id = :id", {id: category.id})
  }
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多