MBJH
MBJH

Reputation: 1639

Using controller to update attributes of another controller and mass-assignment problems in rails 4.1.1

I've just updated my rails app from 3.2.8 to 4.1.1. I did the required alterations to make the transition as smooth as possible. I used to use one controller to update the attributes of another controller like this:

     1. def check_rates
     2. @page_title = "Checkout"
     3. @order = Order.new(params[:order])
     4. @order.customer_ip = request.remote_ip


     5. populate_order


     6. if @order.save

     7.  session[:order_id] = @order.id
     8. @order.order_items.each do |order_item|
     9. @member = Member.find(order_item.member_id)    

    10. **@member.update_attributes(
    11. :order_id =>@order.id)**  
    12. end      
    13. respond_to do |format|
    14. format.html{ redirect_to :action => 'rate_response' } 
    15. format.js
    16. end

    17. else
    18. flash[:notice] = "Error saving buyers address." 

    19. respond_to do |format|
    20. format.html{  render :action => 'index' } 
    21. format.js

    22. end
    23. end
    24.   end

The lines 10 and 11 throw an exception:

*WARNING: Can't mass-assign protected attributes for Member: order_id*

I would be very grateful if someone could help me to solve this issue. I do not use 'attr_accessible' anymore. I use 'params.require(model_name).permit(*attributes) for each of the controller. But what if one controller is used to update attributes of another?

MemberController:
 def member_params
 params.require(member).permit(:city_town, :country, :county_region, :description, 
 :name,:house_flat, :image,  :mob_tel, :postcode_index, :street,
 :image_temp,:latitude,:longitude, :pw_reset_code, :order_id)
 end 


 CheckoutController:
   def order_params
      params.require(:order).permit(:ship_to_house_number,
  :ship_to_street,:ship_to_city,:ship_to_postal_code,
  :ship_to_country,:sender,:receiver,:service_name,:cart_id,
  :ship_to_first_name, :ship_to_last_name,:email, :phone_number,:company_name,:county_region ) 
   end
  def member_params
  params.require(member).permit(:order_id) 
  end    

Member model:
belongs_to :order

Order model:
has_many :members

Upvotes: 2

Views: 977

Answers (2)

MBJH
MBJH

Reputation: 1639

I have done a very silly mistake: in 'params.require(model_name).permit(*args)', I haven't used the model name as symbol:

 params.require(member).permit(*args) ----- WRONG 
 params.require(:member).permit(*args) ---- WRIGHT

Upvotes: 1

Mandeep
Mandeep

Reputation: 9173

Your error *WARNING: Can't mass-assign protected attributes for Member: order_id* clearly tell that you need to pass order_id in your set of permitted attributes. Inside your members_controller.rb you could make a private method memeber_params and do this:

def member_params
  params.require(:member).permit(*attributes, :order_id) #need to add order_id here
end

For more information on strong parameters

Or

As Pavan said if you are using nested_attributes_for then your member_params will be:

def member_params
  params.require(:member).permit(*attributes, :order_attributes{order_attributes})
end

For more information on accepts_nested_attributes

Edit

if you look at your line no. 10-11 you have

@member.update_attributes( :order_id =>@order.id)

You are simply passing order_id into the update call. You haven't permitted order_id

You need to do: @member.update_attributes(member_params)

Upvotes: 0

Related Questions