I want to accomplish the following. I have an object that can be edited. However, it can occur that two people might edit the object at the same time. Instead of locking the object down, I prefer to tell the user how their version differs from the last version that was committed. Kinda like: respond_to do |format| @document = Document.find_by_id(1) @document.attributes = params[:document] @changes = @document.diff(Document.find_by_id(1)) format.html { render :action => "edit" } end The edit screen then renders the changes for the user to compare. The user can then apply some changes or ignore the changes and save. This works fine for regular fields, but when the object has has_many assoctiations, then the following would occur. respond_to do |format| @document = Document.find_by_id(1) @document.attributes = params[:document] # => this call would update the database for all has_many associations @changes = @document.diff(Document.find_by_id(1)) #=> retrieving the previous object state from the database is not possible since the associations have changed format.html { render :action => "edit" } end I also tried to compare the object to the attributes kinda like this; respond_to do |format| @document = Document.find_by_id(1) @changes = @document.diff(params[:document]) format.html { render :action => "edit" } end But then the user''s changes aren''t stored on the object and all updates are lost. Any help is appreciated. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
This sounds like the dirty object feature of Rails 2.1 would work great: http://ryandaigle.com/articles/2008/3/31/what-s-new-in-edge-rails-dirty-objects Maybe even try to utilize some callback methods so you can capture and display the changes to the user: http://railsforum.com/viewtopic.php?id=23001 On Nov 5, 10:38 pm, Franz <franz.obenhau...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I want to accomplish the following. I have an object that can be > edited. However, it can occur that two people might edit the object > at the same time. Instead of locking the object down, I prefer to > tell the user how their version differs from the last version that was > committed. > > Kinda like: > > respond_to do |format| > @document = Document.find_by_id(1) > @document.attributes = params[:document] > @changes = @document.diff(Document.find_by_id(1)) > format.html { render :action => "edit" } > end > > The edit screen then renders the changes for the user to compare. The > user can then apply some changes or ignore the changes and save. > > This works fine for regular fields, but when the object has has_many > assoctiations, then the following would occur. > > respond_to do |format| > @document = Document.find_by_id(1) > @document.attributes = params[:document] # => this call would > update the database for all has_many associations > @changes = @document.diff(Document.find_by_id(1)) #=> retrieving > the previous object state from the database is not possible since the > associations have changed > format.html { render :action => "edit" } > end > > I also tried to compare the object to the attributes kinda like this; > > respond_to do |format| > @document = Document.find_by_id(1) > @changes = @document.diff(params[:document]) > format.html { render :action => "edit" } > end > > But then the user''s changes aren''t stored on the object and all > updates are lost. > > Any help is appreciated.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
The dirty object feature doesn''t work for has_many associations. I solved the problem by wrapping a transaction around the code to revert the changes in the database. I kinda wish, ror could keep the functionality between regular fields and association fields consistent to avoid confusion. kinda like: class Person has_many :cars end>> person = Person.find_by_name("Jack") >> person.cars=> [#<Car id: 2, name: "BMW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">]>> person.cars=[Car.find_by_name("Porsche"), Car.find_by_name("VW")] >> person.cars=> [#<Car id: 1, name: "Porsche", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">, #<Car id: 3, name: "VW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">]>> person.changed?=> true>> person.changes=> {"cars"=>[[#<Car id: 2, name: "BMW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">], [#<Car id: 1, name: "Porsche", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">, #<Car id: 3, name: "VW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">]]}>> person.save #associations are saved in the databaseHowever ror returns the following>> person = Person.find_by_name("Jack") >> person.cars=> [#<Car id: 2, name: "BMW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">]>> person.cars=[Car.find_by_name("Porsche"), Car.find_by_name("VW")] #associations are saved in the database >> person.cars=> [#<Car id: 1, name: "Porsche", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">, #<Car id: 3, name: "VW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">]>> person.changed?=> false>> person.changes=> {} On Nov 7, 12:54 am, JL Smith <autige...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> This sounds like the dirty object feature of Rails 2.1 would work > great:http://ryandaigle.com/articles/2008/3/31/what-s-new-in-edge-rails-dir... > > Maybe even try to utilize some callback methods so you can capture and > display the changes to the user:http://railsforum.com/viewtopic.php?id=23001 > > On Nov 5, 10:38 pm, Franz <franz.obenhau...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > I want to accomplish the following. I have an object that can be > > edited. However, it can occur that two people might edit the object > > at the same time. Instead of locking the object down, I prefer to > > tell the user how their version differs from the last version that was > > committed. > > > Kinda like: > > > respond_to do |format| > > @document = Document.find_by_id(1) > > @document.attributes = params[:document] > > @changes = @document.diff(Document.find_by_id(1)) > > format.html { render :action => "edit" } > > end > > > The edit screen then renders the changes for the user to compare. The > > user can then apply some changes or ignore the changes and save. > > > This works fine for regular fields, but when the object has has_many > > assoctiations, then the following would occur. > > > respond_to do |format| > > @document = Document.find_by_id(1) > > @document.attributes = params[:document] # => this call would > > update the database for all has_many associations > > @changes = @document.diff(Document.find_by_id(1)) #=> retrieving > > the previous object state from the database is not possible since the > > associations have changed > > format.html { render :action => "edit" } > > end > > > I also tried to compare the object to the attributes kinda like this; > > > respond_to do |format| > > @document = Document.find_by_id(1) > > @changes = @document.diff(params[:document]) > > format.html { render :action => "edit" } > > end > > > But then the user''s changes aren''t stored on the object and all > > updates are lost. > > > Any help is appreciated.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
What''s wrong with ruby associations? Somehow association fields don''t have any support for dirty objects nor optimistic locking. I would expect dirty objects to work like this: class Person has_many :cars end>> person = Person.find_by_name("Jack") >> person.cars=> [#<Car id: 2, name: "BMW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">]>> person.cars=[Car.find_by_name("Porsche"), Car.find_by_name("VW")] >> person.cars=> [#<Car id: 1, name: "Porsche", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">, #<Car id: 3, name: "VW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">]>> person.changed?=> true>> person.changes=> {"cars"=>[[#<Car id: 2, name: "BMW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">], [#<Car id: 1, name: "Porsche", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">, #<Car id: 3, name: "VW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">]]}>> person.save #associations are saved in the databaseHowever ror returns the following>> person = Person.find_by_name("Jack") >> person.cars=> [#<Car id: 2, name: "BMW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">]>> person.cars=[Car.find_by_name("Porsche"), Car.find_by_name("VW")] #associations are saved in the database >> person.cars=> [#<Car id: 1, name: "Porsche", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">, #<Car id: 3, name: "VW", created_at: "2008-11-04 03:04:46", updated_at: "2008-11-04 03:04:46">]>> person.changed?=> false>> person.changes=> {} The same problem happens with optimistic locking p1 = Person.find_by_name("Jack") p2 = Person.find_by_name("Jack") p1.cars = [Car.find_by_name("Porsche")] p1.save p2.cars = [Car.find_by_name("BMW")] p2.save I would expect the object to raise an exception, but it doesn''t. Isn''t there a way to unify the behaviour of regular fields and associations? Most objects in my app don''t represent flat tables, but tables that associate each other. Right now I''m forced to having to wrap many attribute updates into a transaction and write my own object comparisons. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---