简体   繁体   中英

Rails App: Method in model or controller

I am a beginner and following along the book "Agile Web Development in Rails" and creating a book-store app. In the process, I am changing the cart to be "smarter" by adding quantity of books in cart and having one line item for multiple items of the same product.

The book recommends (but does not explain), putting a method to add product in the the carts model and calling it on the cart object in the line_items controller. Can I not put this method in the cart controller for the cart object to be able to access it? Is one way of doing it better than the other, or is it a matter of preference?

This is the model code:

class Cart < ActiveRecord::Base
  has_many :line_items, dependent: :destroy

  def add_product(product_id)
    current_item = line_items.find_by_product_id(product_id)
    if current_item
      current_item.quantity = +1
    else 
      current_item = line_items.build(product_id: product_id)
    end
    current_item
  end
end

This is the controller code:

class LineItemsController < ApplicationController
  before_action :set_line_item, only: [:show, :edit, :update, :destroy]

  def create
    @cart = current_cart
    product = Product.find(params[:product_id])
    @line_item = @cart.add_product(product.id)
    @line_item.product = product

    respond_to do |format|
      if @line_item.save
        format.html { redirect_to @line_item.cart, notice: 'Line item was successfully created.' }
        format.json { render :show, status: :created, location: @line_item }
      else
        format.html { render :new }
        format.json { render json: @line_item.errors, status: :unprocessable_entity }
      end
    end
  end

The Rails way is to keep controllers skinny (very simple) and add logic to the model layer whenever possible. This method should be in the model.

To your other question:

Can I not put this method in the cart controller for the cart object to be able to access it?

Specifically, this is a bad idea. You do not want the model (cart object) accessing or calling anything in the controller. The controller should make calls to (depend on) the model layer, but not vice-versa.

Hope this helps! :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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