SitePoint Sponsor |
|
User Tag List
Results 1 to 4 of 4
-
Mar 31, 2008, 18:11 #1
- 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.
-
Mar 31, 2008, 23:15 #2
- 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.
-
Apr 1, 2008, 19:51 #3
- 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!
-
Apr 1, 2008, 22:14 #4
- 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.htmlThere are some things you shouldn't try to code at home.
Bookmarks