SitePoint Sponsor

User Tag List

Results 1 to 4 of 4

Hybrid View

  1. #1
    SitePoint Zealot Xavius's Avatar
    Join Date
    Sep 2005
    Location
    Toronto, Canada
    Posts
    195
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Only applying attribute_update to attributes that have actually changed

    Background: I'm trying to add an edit function to user data on a website. I have it currently setup so a user can click edit and the user is taken to a new page with text fields already populated with their existing information. They can then make changes and click update.

    What I wanted to do is figure out which text fields have different text, from what they were originally populated with, and only update those fields (only update attributes that are different from before). Then keeping track of what fields have been updated alert the user (for instance: "changes have been made to: first name, last name)"

    Code Ruby:
    def edit_manage
      @user_info = User.find_by_id(session[:user_id])
      updated = []
      if request.post?
        @update = User.find_by_id(session[:user_id])
        @update.update_attributes(params)
        #collect original values to compare later
        t = {:first_name => @update.first_name, :middle_name => @update.middle_name,
        :last_name => @update.last_name, :email => @update.email, :about => @update.about}
        params.each do |key,value|
          if t[key] != value #is the original value different from the new?
            @update.update_attribute(key,value)
            updated << key.to_s
          end
        end
     
        changed = ''
        updated.each_with_index do |value,index|
          changed << ', ' unless index.zero?
          changed << value
        end
        flash[:notice] = "#{changed} updated"
        redirect_to :action => 'manage'
      end
    end

    Needless to say this doesn't work and I'm guessing there is a much easier way to do this.

    ===
    got it to work by doing the following:
    Code Ruby:
    def edit_manage 
        @user_info = User.find_by_id(session[:user_id])
     
        if request.post?
          @update = User.find_by_id(session[:user_id])
          t = {:first_name => @update.first_name, :middle_name => @update.middle_name,
          :last_name => @update.last_name, :email => @update.email, :about => @update.about}
          updated = []
          t.each do |key,value|
            if value != params[key]
              @update.update_attribute(key,params[key])
              updated << key.to_s
            end
          end
     
          changed = ''
          updated.each_with_index do |value,index|
            changed << ', ' unless index.zero?
            changed << value
          end
     
          flash[:notice] = "Updated: #{changed}"
          redirect_to :action => 'manage'
        end
      end

    However, I'm still looking for a more efficient way of doing that!
    Last edited by Xavius; Mar 31, 2008 at 20:12.

  2. #2
    SitePoint Enthusiast AllTom's Avatar
    Join Date
    Feb 2008
    Location
    Wherever danger lies...
    Posts
    48
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Note: #update_attribute bypasses validations!

    Edge Rails has #changed_attributes, and lots of stuff related to this is on its way: http://ryandaigle.com/articles/2008/...-dirty-objects. I would back-port that stuff so that when it's finally released, you don't have to change your code. Its syntax is pretty nice anyway.
    There are some things you shouldn't try to code at home.

  3. #3
    SitePoint Zealot Xavius's Avatar
    Join Date
    Sep 2005
    Location
    Toronto, Canada
    Posts
    195
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    In what type of situation(s) would validations come in handy?

    Cool changes, thanks for the heads-up!

  4. #4
    SitePoint Enthusiast AllTom's Avatar
    Join Date
    Feb 2008
    Location
    Wherever danger lies...
    Posts
    48
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    In terms of your text fields that are likely varchar:

    - The database will happily truncate data you send to it, so long inputs will be silently chopped. A validation that checks length will catch this.
    - Validations are an easy way to check for goofball inputs like empty strings.

    In practice, I end up adding one or more validations on every field. Require non-blank text fields, require a username of minimum length, require a password of minimum length, require an e-mail of valid format, require text that's valid XML, require a referenced row that satisfies a certain condition, etc.

    Get all sorts of crazy ideas at: http://api.rubyonrails.org/classes/A...ssMethods.html
    There are some things you shouldn't try to code at home.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •