addressalign-toparrow-leftarrow-rightbackbellblockcalendarcameraccwcheckchevron-downchevron-leftchevron-rightchevron-small-downchevron-small-leftchevron-small-rightchevron-small-upchevron-upcircle-with-checkcircle-with-crosscircle-with-pluscontroller-playcrossdots-three-verticaleditemptyheartexporteye-with-lineeyefacebookfolderfullheartglobegmailgooglegroupshelp-with-circleimageimagesinstagramFill 1light-bulblinklocation-pinm-swarmSearchmailmessagesminusmoremuplabelShape 3 + Rectangle 1ShapeoutlookpersonJoin Group on CardStartprice-ribbonprintShapeShapeShapeShapeImported LayersImported LayersImported Layersshieldstartickettrashtriangle-downtriangle-uptwitteruserwarningyahoo

Re: [ruby-81] copying and comparing model objects

From: William S.
Sent on: Tuesday, March 4, 2008 9:32 PM
On Mar 4, 2008, at 9:03 PM, Loqi wrote:

> The motivation for comparing the data is to avoid writing to the DB  
> unless the user actually changed something. Line 3 above calls  
> update_attributes, which (I think) includes a write to the DB.  Line  
> 8 also writes to the DB. Is this what you meant to do, Will?
>
> Is the version below correct? Only line 7 writes to the database.

Sorry, problem with type code in email without checking it first.  
update_attributes calls save after it merges all the attributes.  You  
would need to ask the object if the params have changed any of the  
attributes. The second version will never return false since there is  
nothing to change to object.

  if !@product.changed?(p­arams[:product])

Would pass the new values into the changed method. You can then diff  
the params from the attributes. Here's another problem. The params  
will not always match the attributes since the fields will all be  
strings and haven't been processed yet. You'll have to do this within  
the model:

   def changed?(new_attribu­tes)
      # We need to save the attributes to restore them later and  
compare against the new attributes.
      @saved_attributes = @attributes.dup
      self.attributes = new_attributes

      # Should work as long as all the fields are present in the form.  
Otherwise custom compare
      # will be needed.
      res = !@saved_attributes.d­iff(@attributes).emp­ty?

      # Resets back to the original attributes.
      @attributes = @saved_attributes
      res
   end

I think this is the easiest way of writing this method. You need to  
use the attributes= method since you'll need to cleanse the values and  
convert them to the correct types. If you compare to what come in from  
the form, the values will never match.  You could write a custom  
compare to check the values, but this gets complicated with multi- 
parameter attributes like dates using the date helper.

Cheers,
- Will

Our Sponsors

People in this
Meetup are also in:

Sign up

Meetup members, Log in

By clicking "Sign up" or "Sign up using Facebook", you confirm that you accept our Terms of Service & Privacy Policy