Will Merrell
2007-Mar-16 18:13 UTC
Handling validation failures on hasmany through records
Hi all, I am fairly new to Ruby and RoR but am making pretty good progress. But this has me stumped and I wonder if anyone can point me in the right direction. I haven''t been able to find any examples on the web that shine the light on this yet. I have a very simple hasmany :through model as follows: class Member < ActiveRecord::Base has_many :member_phones, :dependent => :destroy has_many :phones, :through => :member_phones validates_exclusion_of :first_name, :in => [ "Bozo"], :message => "You don''t belong here" end class MemberPhone < ActiveRecord::Base belongs_to :member belongs_to :phone validates_exclusion_of :name, :in => [ "Foobar" ], :message => "No Foobar Allowed" end class Phone < ActiveRecord::Base has_many :member_phones has_many :people, :through => :member_phones end And this all works fine. The application can do all the CRUD functions, and the validations really fail when they should. My problem is that if I enter a phone named Foobar, it will fail to add the record just as it should, but it does so silently. I cannot figure out how to display an error message for it. I can use <%= error_messages_for ''member'' %> to display the error message if I add a member with a first name of Bozo, but I can''t figure out how to get hold of the error message for the phone. Does anyone know how to get and display the error messages on these associated tables? --Will --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Conrad Taylor
2007-Mar-16 18:28 UTC
Re: Handling validation failures on hasmany through records
Hi, I noticed that within your Phone model is referencing :people. Thus, the Phone model should be class Phone < ActiveRecord::Base has_many :member_phones has_many :members, :through => :member_phones end Good luck, -Conrad On 3/16/07, Will Merrell <will-jkbzaOXREqcCMe7iY93BLQC/G2K4zDHf@public.gmane.org> wrote:> > Hi all, > > I am fairly new to Ruby and RoR but am making pretty good progress. But > this has me stumped and I wonder if anyone can point me in the right > direction. I haven''t been able to find any examples on the web that > shine the light on this yet. > > I have a very simple hasmany :through model as follows: > > class Member < ActiveRecord::Base > has_many :member_phones, :dependent => :destroy > has_many :phones, :through => :member_phones > validates_exclusion_of :first_name, :in => [ "Bozo"], :message => "You > don''t belong here" > end > > class MemberPhone < ActiveRecord::Base > belongs_to :member > belongs_to :phone > validates_exclusion_of :name, :in => [ "Foobar" ], :message => "No > Foobar Allowed" > end > > class Phone < ActiveRecord::Base > has_many :member_phones > has_many :people, :through => :member_phones > end > > And this all works fine. The application can do all the CRUD functions, > and the validations really fail when they should. > > My problem is that if I enter a phone named Foobar, it will fail to add > the record just as it should, but it does so silently. I cannot figure > out how to display an error message for it. > > I can use <%= error_messages_for ''member'' %> to display the error > message if I add a member with a first name of Bozo, but I can''t figure > out how to get hold of the error message for the phone. > > Does anyone know how to get and display the error messages on these > associated tables? > > --Will > > > > > > > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Will Merrell
2007-Mar-16 20:02 UTC
Re: Handling validation failures on hasmany through records
Conrad Taylor wrote:> Hi, I noticed that within your Phone model is referencing :people. > Thus, the Phone model should be > > class Phone < ActiveRecord::Base > has_many :member_phones > has_many :members, :through => :member_phones > end >Thanks Conrad, your right, that was a typo and I have corrected it. However, it does not appear to be the cause of my trouble. The fixed version still fails silently. I am tying to take on each area of RoR in turn. Right now I''m trying to figure out validations. ;^) thanks all, --Will --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Mark Reginald James
2007-Mar-17 22:22 UTC
Re: Handling validation failures on hasmany through records
Will Merrell wrote:> I have a very simple hasmany :through model as follows: > > class Member < ActiveRecord::Base > has_many :member_phones, :dependent => :destroy > has_many :phones, :through => :member_phones > validates_exclusion_of :first_name, :in => [ "Bozo"], :message => "You > don''t belong here" > end > > class MemberPhone < ActiveRecord::Base > belongs_to :member > belongs_to :phone > validates_exclusion_of :name, :in => [ "Foobar" ], :message => "No > Foobar Allowed" > end > > class Phone < ActiveRecord::Base > has_many :member_phones > has_many :people, :through => :member_phones > end > > And this all works fine. The application can do all the CRUD functions, > and the validations really fail when they should. > > My problem is that if I enter a phone named Foobar, it will fail to add > the record just as it should, but it does so silently. I cannot figure > out how to display an error message for it. > > I can use <%= error_messages_for ''member'' %> to display the error > message if I add a member with a first name of Bozo, but I can''t figure > out how to get hold of the error message for the phone. > > Does anyone know how to get and display the error messages on these > associated tables?Something like this? <% member_phones = @member.member_phones.find(:all, :include => :phone) for @member_phone in member_phones @phone = @member_phone.phone %> <%= error_messages_for :member_phone %> <%= text_field :phone, :number %> <% end %> -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Will Merrell
2007-Mar-18 15:02 UTC
Re: Handling validation failures on hasmany through records
Mark Reginald James wrote:> Will Merrell wrote: > > >> I have a very simple hasmany :through model as follows: >> >> class Member < ActiveRecord::Base >> has_many :member_phones, :dependent => :destroy >> has_many :phones, :through => :member_phones >> validates_exclusion_of :first_name, :in => [ "Bozo"], :message => "You >> don''t belong here" >> end >> >> class MemberPhone < ActiveRecord::Base >> belongs_to :member >> belongs_to :phone >> validates_exclusion_of :name, :in => [ "Foobar" ], :message => "No >> Foobar Allowed" >> end >> >> class Phone < ActiveRecord::Base >> has_many :member_phones >> has_many :members, :through => :member_phones >> end >> >> And this all works fine. The application can do all the CRUD functions, >> and the validations really fail when they should. >> >> My problem is that if I enter a phone named Foobar, it will fail to add >> the record just as it should, but it does so silently. I cannot figure >> out how to display an error message for it. >> >> I can use <%= error_messages_for ''member'' %> to display the error >> message if I add a member with a first name of Bozo, but I can''t figure >> out how to get hold of the error message for the phone. >> >> Does anyone know how to get and display the error messages on these >> associated tables? >> > > Something like this? > > <% member_phones = @member.member_phones.find(:all, :include => :phone) > for @member_phone in member_phones > @phone = @member_phone.phone > %> > <%= error_messages_for :member_phone %> > <%= text_field :phone, :number %> > <% end %> >Hi Mark, Thanks for the reply, Perhaps I am being dumb, but I don''t really understand how your suggestion helps me. When I try to use the code you supplied, it still fails silently. Could you explain what you expect this to do, (with a little background) so I can tailor it to my situation? A word or two of background on my part may help. The way I have found to make the updates to the associated tables is with a supporting function (called update_phones) in the member_phones model which is called from the update action in the members controller. I don''t know if this is the proper way to do this, but it was the first thing I found that worked. I suppose my problem is that this technique hides the validation failures. Is there a more proper way to add the post parameters to the model for updating? The complete member_phones.rb file is as follows: class MemberPhone < ActiveRecord::Base belongs_to :member belongs_to :phone validates_presence_of :name validates_presence_of :member_id validates_presence_of :phone_id validates_exclusion_of :name, :in => [ "Foobar" ], :message => "No Foobar Allowed" before_destroy { |record| if( MemberPhone.find(:all, :conditions => {:phone_id => record.phone_id}).length < 2 ) Phone.find(record.phone_id).destroy end } def update_phone(phonename, phonenumber) self.name = phonename self.phone.number = phonenumber saved = self.save saved = self.phone.save return saved end end Thanks, -- Will hasmany :questions, :throught => :acts_as_nuby! --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Mark Reginald James
2007-Mar-19 07:13 UTC
Re: Handling validation failures on hasmany through records
Will Merrell wrote:> Perhaps I am being dumb, but I don''t really understand how your > suggestion helps me. When I try to use the code you supplied, it still > fails silently. Could you explain what you expect this to do, (with a > little background) so I can tailor it to my situation?Will, I thought your problem was how to display the errors on the through model, but I think your problem is also not preventing the update of both the phone and member_phone if there was a validation failure on one of them. You want to make sure that no record is updated if either the Phone or MemberPhone has errors. To do this you can add a validates_associated directive: class MemberPhone < ActiveRecord::Base validates_associated :phone def update_phone(phonename, phonenumber) self.name = phonename self.phone.number = phonenumber phone.save if saved = save return saved end end But sometimes this is a problem because you get a "phone is invalid" error message in your member_phone error list. If so, you can instead use: class MemberPhone < ActiveRecord::Base def update_phone(phonename, phonenumber) self.name = phonename self.phone.number = phonenumber valid_phone = phone.valid? if valid_combo = valid? && valid_phone save(false) phone.save(false) end return valid_combo end end (For simplicity, I''m only dealing with the situation in which an existing number is updated, rather than a new number added.) -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Will Merrell
2007-Mar-19 11:10 UTC
Re: Handling validation failures on hasmany through records
Mark Reginald James wrote:> Will, I thought your problem was how to display the errors on the through > model, but I think your problem is also not preventing the update of both > the phone and member_phone if there was a validation failure on one of them. >Mark, Thanks for the reply and your time on this. I agree that the code I originally posted probably had the problem you suggest. I was (and is) work in progress. However, that is not the problem I was originally asking about. My question was, and is, how to get and display the errors when they do arise. The model, (when adjusted to prevent saving one when the other fails,) does work. If I try to enter some data that causes a validation failure, the record is indeed not saved. If a pepper the update_phone code with logger.info calls, I can see that Phone.errors does contain the error messages I would expect. My problem is I cannot find any code that I can put in the view that lets me display the errors. Examples: <%= error_messages_for ''member'' %> <---- This works, but only for failures in members <%= error_messages_for @member %> <---- Fails to compile <%= error_messages_for ''member''.member_phones[1] %> <---- Fails to compile <%= error_messages_for ''member.member_phones'' %> <---- Fails to compile <%= error_messages_for ''member.member_phones[1]'' %> <---- Fails to compile <%= error_messages_for ''member.member_phones.find(1)'' %> <---- Fails to compile <% @mphone = @member.member_phones.find(1) %> <%= error_messages_for ''mphone'' %> <----- Compiles, but doesn''t do anything So I can raise the errors, I can control what goes into the database, what I can''t do is tell the user why his change was not saved! Any ideas????? -- Will --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Mark Reginald James
2007-Mar-19 12:44 UTC
Re: Handling validation failures on hasmany through records
Will Merrell wrote:> <% @mphone = @member.member_phones.find(1) %> > <%= error_messages_for ''mphone'' %> <----- Compiles, but > doesn''t do anythingerror_messages_for works on controller instance variables, so the above is on the right track. But when you do a find you''re reloading from the db, not using the objects to which your response handling has added errors. So I think I mislead you when in my original reply I used a find in the view as a shorthand to generate the required data structure. So after you''ve manipulated and validated the objects in the member_phone collection in the controller action, you want something like: <% @mphone = @member.member_phones.first %> <%= error_messages_for :mphone %> or to do them all: <% for @mphone in @member.member_phones @phone = @mphone.phone %> <%= error_messages_for :mphone %> <%= error_messages_for :phone %> <% end %> -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---