【问题标题】:Rails associations one column to many objects of same typeRails 将一列关联到许多相同类型的对象
【发布时间】:2018-07-07 01:52:10
【问题描述】:

在我的 Rails 应用程序中,我有一个用户、产品和订单表。用户可以在每个订单中购买多个产品。发生这种情况时,我将项目作为字符串存储在订单表的列 (product_id) 中。例如,如果用户购买了 3 种不同的产品,产品 id 将存储在我的订单表的 product_id 列中:product_id: "12, 97, 132"

我将用户与订单相关联,例如用户has_many :orders 和订单belongs_to :user。对于每个用户,我想要做的是显示他们之前的订单以及该订单中包含的产品。通过关联,我可以轻松获得订单:@orders = current_user.orders.all 但是有没有办法将产品与订单关联起来,因为如果多个产品可以与一个订单关联?

现在,在我的订单模型中,我添加了一个 attr_accessor :products,在我的控制器中我有:

  def orders
    @orders = current_user.orders.all
    @orders.each do |order|
      items = Product.find(order.product_id.split(','))
      order.products = items
    end
  end

这可行,但是如果参考列中存储了多个产品 ID,是否有一种“预构建”的方式来关联订单和产品?

【问题讨论】:

  • 您应该避免将<model_name>_id 用于与(单个)关系ID 无关的任何内容。

标签: ruby-on-rails ruby


【解决方案1】:

处理您的案例的更好方法是通过连接表在产品和订单之间创建多对多关系。

1 - 创建 orders_products 表

class CreateOrdersProducts < ActiveRecord::Migration
    def change
      create_table :orders_products do |t|
        t.references :order, index: true
        t.references :product, index: true
      end
    end
end

2 - 在 models/order.rb 中

class Order
  has_and_belongs_to_many  :products
end

3 - 在 models/product.rb 中

class Product
  has_and_belongs_to_many  :orders
end

创建关联后,您可以使用以下方式将产品保存到特定订单:

order.products = products
order.save

获取特定订单的产品:

order.products

【讨论】:

    【解决方案2】:

    您应该在productsorders 之间创建一个连接表,我们将其命名为line_items

    ## app/models/product.rb
    class Product < ApplicationRecord
      has_many :line_items
      has_many :orders, through: :line_items
    end
    
    ## app/models/line_item.rb
    class LineItem < ApplicationRecord
      belongs_to :product
      belongs_to :order
    end
    
    ## app/models/order.rb
    class Order < ActiveRecord::Base
      has_many :line_items
      has_many :products, through: :line_items
    end
    

    为了关联订单和产品,只需像这样使用内置的has_many

    @order = Order.first
    @order.products.count # => 0
    
    @order.product_ids = [12, 97, 132]
    @order.products.count # => 3
    

    【讨论】:

    • 有趣。我会试一试。谢谢。
    【解决方案3】:

    如果一个订单有_many 个产品和一个产品有_many 个订单,您可以在不使用您提到的字符串表示法的情况下关联产品。然后你只需要一个引用两者的连接表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      • 2015-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-12-08
      • 1970-01-01
      相关资源
      最近更新 更多