Reputation: 191
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
Upvotes: 3
Views: 1509
Reputation: 2633
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! :)
Upvotes: 3