Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When assigning attributes, you must pass a hash as an argument

I am following Agile Web Development with Rails 4. Chapter Cart 9 Cart Creation. When I want to update a cart, I get the following Error Notification: When assigning attributes, you must pass a hash as an arguments. CartController#update.

class CartsController < ApplicationController
  include CurrentCart
  before_action :set_cart, only: [:show, :edit, :update, :destroy]
  rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart

  def index
    @carts = Cart.all
  end

  def show
  end

  def new
    @cart = Cart.new
  end

  def edit
  end

  def create
    @cart = Cart.new(cart_params)

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

  def update
    @cart = Cart.find(params[:id])

    respond_to do |format|
      if @cart.update_attributes(params[:cart])
        format.html { redirect_to @cart, notice: 'Cart was successfully updated.' }
        format.json { render :show, status: :ok, location: @cart }
      else
        format.html { render :edit }
        format.json { render json: @cart.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @cart.destroy if @cart.id == session[:card_id]
    session[:card_id] = nil
    respond_to do |format|
      format.html { redirect_to store_url, notice: 'Your cart is currently empty.' }
      format.json { head :no_content }
    end
  end

  private

  def set_cart
    @cart = Cart.find(params[:id])
  end

  def cart_params
    params[:cart]
  end

  def invalid_cart
    logger.error "Attempt to access invalid cart #{params[:id]}"
    redirect_to store_url, notice: 'Invalid cart'
  end
end
like image 727
Keeic Avatar asked Oct 16 '14 06:10

Keeic


2 Answers

Your params is probably an instance of ActionController::Parameters

If so, you need to permit the attributes you want to use, like so:

def cart_params
  params.require(:cart).permit(:attribute1, :attribute2, :attribute3)
end
like image 154
Robert Falkén Avatar answered Nov 01 '22 03:11

Robert Falkén


Try this: In your update method replace

if @cart.update_attributes(params[:cart])

by

if @cart.update_attributes(cart_params)

In your cart_params private method do this:

def cart_params
  params.require(:cart).permit(:attribute1, :attribute2, :attribute3)
end

With Rails 4, the concept of strong parameters has been introduced which basically forbids mass assignment of attributes in the controller. This means that the mass assingment protection that was once in model (attr_accessible) has now been moved to the controller. Hence in your models you no more need to use this:

attr_accessible :attribute1, attribute 2 #attributes that can be mass-assinged
attr_protected :attribute3 #attribute that is protected and cannot be mass-assinged

Instead you can now do this in your controller through :

 params.require(:cart).permit(:attribute1, :attribute2, :attribute3)

This means that only attribute1, attribute2. attribute3 of cart are accessible while other are protected attributes

like image 41
Aaditi Jain Avatar answered Nov 01 '22 04:11

Aaditi Jain