Ruben Ascencio
2010-Jun-24 16:02 UTC
Parent model running validations on all existing children
In my application, a Language has many Phrases. Here is my code: #language model has_many :phrases accepts_nested_attributes_for :phrases #phrase model validates_presence_of :value belongs_to :language #languages controller def edit @language = Language.find(params[:id]) # Let''s say we only want to update some of the phrases (e.g. by category, date, etc) @phrases = @language.phrases.all(:limit => 3) end def update @language = Language.find(params[:id]) if @language.update_attributes(params[:language]) flash[:notice] = "Successfully updated language." redirect_to edit_language_path(@language) else render :action => ''edit'' end end # project edit view <% form_for @language do |f| %> <%= f.error_messages %> <p> <%= f.label :name %><br /> <%= f.text_field :name %> </p> <% f.fields_for :phrases, @phrases do |phrases_form| %> <p> <%= phrases_form.label :value %> <%= phrases_form.text_field :value %> </p> <% end %> <p><%= f.submit %></p> <% end %> When I submit the form, if at least one of the phrases being saved is an existing record, every single phrase corresponding to @language will be validated, instead of running validations only in the three phrases being updated. That problem isn''t present when all of the phrases being saved are new records. -- Posted via http://www.ruby-forum.com/. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Ruben Ascencio
2010-Jun-24 17:10 UTC
Re: Parent model running validations on all existing children
I was expecting Rails to only validate the phrase that is being updated, here you can see it''s validating all of the existing phrases: $ script/console Loading development environment (Rails 2.3.5)>> lang = Language.first=> #<Language id: 1, name: "Italiano">>> lang.phrases=> [#<Phrase id: 7, value: "Buona notte", language_id: 1>, #<Phrase id: 10, value: "Ciao", language_id: 1>, #<Phrase id: 11, value: "Prego", language_id: 1>]>> lang.phrases_attributes = [{:id => "7", :value => "Buon giorno"}]=> [{:value=>"Buon giorno", :id=>"7"}]>> lang.saveValidating: Buon giorno Validating: Ciao Validating: Prego => true My models, again, now with the added "before_validation" callback: class Language < ActiveRecord::Base has_many :phrases accepts_nested_attributes_for :phrases end class Phrase < ActiveRecord::Base validates_presence_of :value belongs_to :language def before_validation logger.debug "\nValidating: #{self.value}\n" end end Validating all phrases is a real problem in my app, as I have tens of thousands; Is there a way to avoid this? Is this normal behavior for Rails? Ruben Ascencio wrote:> In my application, a Language has many Phrases. Here is my code: > > #language model > has_many :phrases > accepts_nested_attributes_for :phrases > > #phrase model > validates_presence_of :value > belongs_to :language > > #languages controller > def edit > @language = Language.find(params[:id]) > # Let''s say we only want to update some of the phrases (e.g. by > category, date, etc) > @phrases = @language.phrases.all(:limit => 3) > end > > def update > @language = Language.find(params[:id]) > if @language.update_attributes(params[:language]) > flash[:notice] = "Successfully updated language." > redirect_to edit_language_path(@language) > else > render :action => ''edit'' > end > end > > # project edit view > <% form_for @language do |f| %> > <%= f.error_messages %> > <p> > <%= f.label :name %><br /> > <%= f.text_field :name %> > </p> > <% f.fields_for :phrases, @phrases do |phrases_form| %> > <p> > <%= phrases_form.label :value %> > <%= phrases_form.text_field :value %> > </p> > <% end %> > <p><%= f.submit %></p> > <% end %> > > When I submit the form, if at least one of the phrases being saved is > an existing record, every single phrase corresponding to @language > will be validated, instead of running validations only in the three > phrases being updated. That problem isn''t present when all of the > phrases being saved are new records.-- Posted via http://www.ruby-forum.com/. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.