简体   繁体   English

Rails路线来更新关联模型的属性

[英]Rails route to update an associated model's attributes

I have a Cart , CartProduct , and Product model. 我有一个CartCartProductProduct模型。 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_productremove_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM