[英]Rails route to update an associated model's attributes
I have a Cart
, CartProduct
, and Product
model. 我有一个
Cart
, CartProduct
和Product
模型。 Whenever a product is added to the cart, the CartProduct
model, which represents the items in the shopping cart, has an attribute quantity
that's updated accordingly. 每当将产品添加到购物
CartProduct
,代表购物车中商品的CartProduct
模型都会具有相应的属性quantity
。 Currently I'm sending PATCH
requests on Cart
to update the Cart
s associated CartProduct
models. 当前,我正在
Cart
上发送PATCH
请求,以更新Cart
的关联CartProduct
模型。
My question is: when I want to update a shopping cart item, would it be better to have add_product
, remove_product
, etc. methods in the CartProduct
model, or should I have those methods in the Cart
model (my current setup below, which functions just fine)? 我的问题是:当我想更新购物车商品时,最好在
CartProduct
模型中使用add_product
, remove_product
等方法,还是应该在Cart
模型中使用这些方法(下面的当前设置)正好)? Or is this up to personal preference? 还是取决于个人喜好?
Please note that the code is incomplete; 请注意,代码不完整。 I just picked out the important parts for this question:
我刚刚选择了这个问题的重要部分:
class Cart < ActiveRecord::Base
has_many :cart_products, inverse_of: :cart, dependent: :destroy
has_many :products, through: :cart_products, source: :product
def add_product(product_id) #directed here from PATCH request
#pulls the associated cart_product for this cart and updates
end
def remove_product(product_id) #directed here from PATCH request
end
end
class CartProduct < ActiveRecord::Base
belongs_to :cart, inverse_of: :cart_products
belongs_to :product, inverse_of: :cart_products
#or should add_product, remove_product methods go here instead?
end
class Product < ActiveRecord::Base
has_many :cart_products, inverse_of: :product, dependent: :destroy
has_many :carts, through: :cart_products, source: :cart
end
When a user increments the quantity of a shopping cart item, what's actually being updated is the CartProduct
model, not the Cart
model - so this worries me because I'm sending a PATCH
request on the Cart
, while I suppose it would make more sense to have a route/method on the CartProduct
model because that's the actual model being updated. 当用户增加购物车商品的数量时,实际上正在更新的是
CartProduct
模型,而不是Cart
模型-因此这让我感到担心,因为我在Cart
上发送了PATCH
请求,而我认为这样做更有意义在CartProduct
模型上具有路线/方法,因为这是要更新的实际模型。
I think what you're asking would be left up to personal preference. 我认为您的要求将取决于个人喜好。
My preference would be to keep it exactly as you have it and call add_product
from your Cart
model. 我的喜好是将其保留为您所拥有的名称,然后从
Cart
模型中调用add_product
。
Others may suggest creating a completely new class, observer, etc to handle that relationship between the two models but what you end up doing is making one class that is dependent upon two models rather than keeping what you have and just having one models method dependent on one other model's attribute. 其他人可能建议创建一个全新的类,观察者等来处理这两个模型之间的关系,但是您最终要做的是使一个类依赖于两个模型,而不是保留您拥有的类而仅使一个模型方法依赖另一个模型的属性。
You mixing up what controllers and models do in MVC. 您混合了MVC中控制器和模型的功能。
Models are how you implement the business logic in your application, and how the different objects are tied together. 模型是如何在应用程序中实现业务逻辑,以及如何将不同的对象捆绑在一起。 Models should not know anything about PUT, POST, PATCH or even that there is a current request, its not their job.
模型不应该对PUT,POST,PATCH有所了解,甚至不知道有当前请求,这也不是他们的工作。
So if you are creating a method in your model to handle a specific kind of request than your doing it wrong. 因此,如果您要在模型中创建一种方法来处理特定种类的请求,那么您做错了。
Controllers are responsible for responding to requests. 控制器负责响应请求。 Together with routes they build the RESTful interface that your app exposes.
它们与路由一起构建您的应用程序公开的RESTful接口。
Exactly how to deal with nested resources like in this case is a matter of opinion. 在这种情况下,究竟如何处理嵌套资源确实是一个问题。
I'm going to use the more common term line item instead of CartProduct for clarity: 为了清楚起见,我将使用更常见的术语订单项而不是CartProduct:
Prefix Verb URI Pattern Controller#Action
products GET /products(.:format) products#index
POST /products(.:format) products#create
product GET /products/:id(.:format) products#show
PATCH /products/:id(.:format) products#update
PUT /products/:id(.:format) products#update
DELETE /products/:id(.:format) products#destroy
cart_line_items GET /carts/:cart_id/line_items(.:format) line_items#index
POST /carts/:cart_id/line_items(.:format) line_items#create
line_item GET /line_items/:id(.:format) line_items#show
PATCH /line_items/:id(.:format) line_items#update
PUT /line_items/:id(.:format) line_items#update
DELETE /line_items/:id(.:format) line_items#destroy
carts GET /carts(.:format) carts#index
POST /carts(.:format) carts#create
cart GET /carts/:id(.:format) carts#show
PATCH /carts/:id(.:format) carts#update
PUT /carts/:id(.:format) carts#update
DELETE /carts/:id(.:format) carts#destroy
In many cases using nested attributes and creating/updating/deleting child records is a good solution - but it often leads to the temptation of creating a very limited set up of actions that do everything. 在许多情况下,使用嵌套属性和创建/更新/删除子记录是一个很好的解决方案-但它常常导致创建非常有限的动作集的诱惑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.