Passing parameters to update nested attributes

12,913

You are passing the wrong params hash into the update_attributes call. It should be

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

To clarify, passing :id or :quotation isn't doing anything special. Symbols in Ruby are just immutable string. So using :id or :quotation is the equivalent of passing a string "id" or "quotation". params[] is a hashmap of all the form parameters posted by your page.

In the params hash, there is a key of the type you are passing (in this case quotation) which has a value of another hash containing all of the posted fields associated to the quotation in your view and the values of those fields.

The ID, controller and action values in the params hash comes from the route values from the url.

E.g.

params[] = 
{ 
      :controller => 'quotations',
      :action => 'edit',
      :id => '1',
      :quotation => 
      {
          :quote_text=> "Blah", 
          :author=> "Steve", 
          :quote_type=> "1", 
          :user_id=> "6"
      }
}
Share:
12,913
Edward Castaño
Author by

Edward Castaño

I'm an MBA turned hacker. Read about my experience at www.mbahacks.com.

Updated on June 04, 2022

Comments

  • Edward Castaño
    Edward Castaño about 2 years

    I'm working on a very basic practice application where a user can create multiple quotations. The problem I'm having is that I can't update my quotations. I've many things and have read through other questions here and on google, but can't figure out what I am doing wrong. Here is my code:

    #User Model
        class User < ActiveRecord::Base
          has_many :quotations, :dependent => :destroy
          attr_accessible :quotations
          accepts_nested_attributes_for :quotations, :allow_destroy => true
        end
    
    #Quotations Model
    class Quotation < ActiveRecord::Base
      attr_accessible :quote_text, :author, :quote_type, :category, :tags, :user_id
      belongs_to :user
    end
    

    Quotations Controller

    class QuotationsController < ApplicationController
      before_filter :get_user
    
      def get_user
        @user = User.find(params[:user_id])
      end 
    
      def edit
        @quotation = @user.quotations.find(params[:id])
      end
    
      def update
        @quotation = @user.quotations.find(params[:id]) 
        if @quotation.update_attributes(params[:id])
          redirect_to user_quotation_path :notice  => "Successfully updated quotation."
        else
          render :action => 'edit'
        end
      end    
    
    end
    
    • Edward Castaño
      Edward Castaño over 12 years
      Solved if @quotation.update_attributes(params[:id]) Is only updating the id, which means nothing changed, because the id is not on the edit form. The correct code would pass params[:quotation] to update the qoutation parameters. if @quotation.update_attributes(params[:quotation])
  • dnatoli
    dnatoli over 12 years
    You answer isn't entirely correct and a bit misleading to others. :quotation isn't a symbol for the parameters of quotation, it is simply a string. I have updated my answer to give you a better idea of what is happening..
  • Edward Castaño
    Edward Castaño over 12 years
    Thanks for the clarification. I updated my answer to reflect your point and marked your answer as the accepted answer. Thanks for taking the time to elaborate the details of passing parameters. It's the clearest explanation I have yet to see. A huge help!
  • Edward Castaño
    Edward Castaño over 12 years
    Your explanation above about parameter passing is right on, except that :quotation is a symbol. Don't know if we're just mincing words. stackoverflow.com/questions/6428318/… troubleshooters.com/codecorn/ruby/symbols.htm
  • dnatoli
    dnatoli over 12 years
    Sorry, my explanation wasn't very clear. Yes :quotation is a symbol. But a symbol in ruby is just an immutable string. I've updated my answer with a link that should give you a good idea of the differences between string and symbols in ruby.