【问题标题】:Shopping cart Active Record Associations购物车 Active Record 关联
【发布时间】:2022-01-26 17:12:16
【问题描述】:

我正在尝试在 Rails 应用程序中实现购物车。为此,我试图将这些模型粘合在一起:

user.rb

class User < ApplicationRecord
  has_many :cart_contents
end

cart_content.rb:

class CartContent < ApplicationRecord
  belongs_to :user
  has_one :product
end

product.rb

class Product < ApplicationRecord
end

为了测试这种安排是否有效,我在控制台中尝试了这个:

irb(main):006:0> cc = CartContent.new
=> 
#<CartContent:0x000055679d802a28
...

irb(main):008:0> cc.user = User.find(1)
  User Load (0.2ms)  SELECT "users".* FROM [...]
=> #<User id: 1, email: "mail@example.com", ...

irb(main):010:0> cc.product = Product.find(1)
  Product Load (0.1ms)  SELECT "products".* FROM [...]                                                                      
/[...]/activemodel-7.0.0/lib/active_model/attribute.rb:211:
in `with_value_from_database': can't write unknown attribute `cart_content_id` (ActiveModel::MissingAttributeError)

我在这里缺少什么?我需要在product.rb 中表明与cart_content 的关系吗?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    一种可能的解决方案:您可能希望将您的CartContent 改为belongs_to :product

    class CartContent < ApplicationRecord
      belongs_to :user
      has_one :product # change this to belongs_to
    end
    
    cc.product = Product.find(1)
    
    # .. can't write unknown attribute `cart_content_id` (ActiveModel::MissingAttributeError)
    

    has_one 将期望您的 products 表有一个 cart_content_id 列。

    参见指南部分2.7 Choosing Between belongs_to and has_one

    【讨论】:

    • 这是修复的一部分,谢谢。 :)
    【解决方案2】:

    为此,您需要在模型之间建立关系。正如 Jared 在 this link 中提到的,要存在外键,您需要指定一个 belongs_to 约束。

    区别在于您放置外键的位置(它在表中用于声明belongs_to关联的类)

    class Product < ApplicationRecord
      belongs_to :cart_content
    end
    

    如果您还想访问用户的所有产品,您可以在下面进行,但您可能不需要through 关系。

    class User < ApplicationRecord
      has_many :cart_contents
      has_many :products, through: :cart_contents
    end
    

    那么您的产品模型将如下所示

    class Product < ApplicationRecord
      belongs_to :cart_content
      belongs_to :user
    end
    

    【讨论】:

    • 感谢有关 has_many through: 关系的提示,这当然很方便。
    【解决方案3】:

    我找到了适合我的解决方案。

    product.rb

    class Product < ApplicationRecord
      has_one :cart_content
    end
    

    cart_content.rb

    class CartContent < ApplicationRecord
      belongs_to :user
      belongs_to :product
    end
    

    user.rb

    class User < ApplicationRecord
      has_many :cart_contents
      has_many :products, through: :cart_contents # for convenience
    end
    

    Rails 不再需要 Product 上的 cart_content_id 列,并且以下命令都可以在控制台中运行:

    user = User.first
    product = Product.first
    cc = CartContent.new
    cc.user = user
    cc.product = product
    cc.save
    
    User.first.products # returns products currently in cart
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 2017-10-14
      • 2014-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多