Hello! Has anyone come across a nice, elegant way to handle multiple validation failures on a single field? For example... in the typical login, you might have an email field that has three validations: not blank, less than a max length and matches a format regex. But if I submit the login/signup form with a blank I get back: # Email address is too short (minimum is 6 characters) # Email address should look like an email address. # Email address can''t be blank I''d rather be able to specify (cleanly and easily) on a model some kind of order of importance and then only show the first validation failure for that field. Thoughts? Advice? TIA! -Danimal -- 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.
Marnen Laibow-Koser
2010-Jan-12 22:43 UTC
Re: Multiple validations on a field... grouping them? only o
Danimal wrote:> Hello! > > Has anyone come across a nice, elegant way to handle multiple > validation failures on a single field? For example... in the typical > login, you might have an email field that has three validations: not > blank, less than a max length and matches a format regex. But if I > submit the login/signup form with a blank I get back: > > # Email address is too short (minimum is 6 characters) > # Email address should look like an email address. > # Email address can''t be blank > > I''d rather be able to specify (cleanly and easily) on a model some > kind of order of importance and then only show the first validation > failure for that field.Why? As a user, I find it extremely annoying when I fix one validation error, submit the form, and get shown a different error. I''d rather see all the validation errors at once so I can fix them all at the same time.> > Thoughts? Advice?Don''t do that. :)> > TIA! > > -DanimalBest, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. --000325558e166e8d30047cff60f1 Content-Type: text/plain; charset=ISO-8859-1 -- 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. --000325558e166e8d30047cff60f1--
Rob Biedenharn
2010-Jan-13 18:34 UTC
Re: Multiple validations on a field... grouping them? only one?
On Jan 12, 2010, at 4:51 PM, Danimal wrote:> Hello! > > Has anyone come across a nice, elegant way to handle multiple > validation failures on a single field? For example... in the typical > login, you might have an email field that has three validations: not > blank, less than a max length and matches a format regex. But if I > submit the login/signup form with a blank I get back: > > # Email address is too short (minimum is 6 characters) > # Email address should look like an email address. > # Email address can''t be blank > > I''d rather be able to specify (cleanly and easily) on a model some > kind of order of importance and then only show the first validation > failure for that field. > > Thoughts? Advice? > > TIA! > > -DanimalThese all seem to be aspects of the same thing. If an email looks like an email address, then it is presumably at least 6 characters (a@b.us ) and thus non-blank. validates_format_of :email_address, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :message => ''should look like an email address'' or even some more sophisticated expression. You could toss in :allow_nil=>false or :allow_blank=>false even though the default for both is already false. You could write your own validate() method and take over all the validation, but that might not be a viable option if there are several fields with validations. -Rob Rob Biedenharn http://agileconsultingllc.com Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org -- 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.
Alpha Blue
2010-Jan-13 20:56 UTC
Re: Multiple validations on a field... grouping them? only one?
I have to agree with both Marnen and Rob here. First, validations are not meant to make a user happy. It''s to ensure that proper validation is met before data is inserted into your database. Therefore, the more accurate you validate your forms, the least likely you are to have some type of data corruption occur within your tables. It is much easier to review all of the validations taking place than to specify for specific entries because more than one could be incorrect. Second, you can definitely write your own validations but keep some things in mind when you do so. If you are going to reuse the validation (most likely you are) place it in your initializers so that your environment remains clean and you also can reuse the validator at some point in time. I have the following custom validator located in validators.rb in my config -> initialize folder. In the example below, this custom validation is making sure that two fields are identical. def self.validates_is_exact(*attr_names) options = attr_names.extract_options! validates_each(*(attr_names << options)) do |record, attr_name, value| if record.send( options[:compare_field] ) != value record.errors.add(attr_name, options[:message]) end end true end validates_is_exact :field_one, :compare_field => :field_two I hope that helps answer your question. -- 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.
Marnen Laibow-Koser
2010-Jan-13 21:19 UTC
Re: Multiple validations on a field... grouping them? only
Alpha Blue wrote:> I have to agree with both Marnen and Rob here. > > First, validations are not meant to make a user happy. It''s to ensure > that proper validation is met before data is inserted into your > database.Not really. Validations are meant to make users happy, sort of. The database should have its own check and key constraints so that invalid data can never make it in there. App-layer validations exist so that the app UI can be better and so that complex constraints that are impractical to put in the DB are possible (such as e-mail regex validation?).> Therefore, the more accurate you validate your forms, the > least likely you are to have some type of data corruption occur within > your tables.No! You *must not* rely solely on Rails validations to prevent your database from getting corrupted.> It is much easier to review all of the validations taking > place than to specify for specific entries because more than one could > be incorrect.Yes.> > Second, you can definitely write your own validations but keep some > things in mind when you do so. If you are going to reuse the validation > (most likely you are) place it in your initializers so that your > environment remains clean and you also can reuse the validator at some > point in time.Again, no. Put it in a module or something, same as you would any other AR class method.> > I have the following custom validator located in validators.rb in my > config -> initialize folder.That should be in a module, probably in your lib folder. You could call it from a plugin, or use environment.rb or an initializer to include it in AR::Base.> > In the example below, this custom validation is making sure that two > fields are identical. > > def self.validates_is_exact(*attr_names) > options = attr_names.extract_options! > validates_each(*(attr_names << options)) do |record, attr_name, value| > if record.send( options[:compare_field] ) != value > record.errors.add(attr_name, options[:message]) > end > end > true > end > > validates_is_exact :field_one, :compare_field => :field_twoBad example. The only time you should ever need to do this is in the case already covered by validates_confirmation_of. If you have two fields in the DB that should always be identical, then remove one of them.> > I hope that helps answer your question.Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- 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.
Marnen Laibow-Koser
2010-Jan-13 21:21 UTC
Re: Multiple validations on a field... grouping them? only
Rob Biedenharn wrote:> On Jan 12, 2010, at 4:51 PM, Danimal wrote: > >> # Email address can''t be blank >> >> I''d rather be able to specify (cleanly and easily) on a model some >> kind of order of importance and then only show the first validation >> failure for that field. >> >> Thoughts? Advice? >> >> TIA! >> >> -Danimal > > These all seem to be aspects of the same thing. If an email looks > like an email address, then it is presumably at least 6 characters > (a@b.us > ) and thus non-blank. > > validates_format_of :email_address, > :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, > :message => ''should look like an email address'' > > or even some more sophisticated expression.Please don''t use a more sophisticated expression. The only such *correct* regexps I''m aware of for e-mail addresses are on the order of a page in length. An *incorrect* regexp will reject valid e-mail addresses (this actually happens surprisingly frequently). Just check for the @ and . and trust the user for the rest.> You could toss > in :allow_nil=>false or :allow_blank=>false even though the default > for both is already false. > > You could write your own validate() method and take over all the > validation, but that might not be a viable option if there are several > fields with validations.In the latter case, it''s easy to write custom validators.> > -Rob > > Rob Biedenharn http://agileconsultingllc.com > Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.orgBest, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- 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.
Alpha Blue
2010-Jan-13 21:27 UTC
Re: Multiple validations on a field... grouping them? only
Marnen Laibow-Koser wrote:> Bad example. The only time you should ever need to do this is in the > case already covered by validates_confirmation_of. If you have two > fields in the DB that should always be identical, then remove one of > them. >I''m sorry, but I have to disagree. In the case my example, I referred to an example of virtual pages versus hard controller pages. In the case of matching fields, if a controller redirect occurs to a statically created page, I want the name field and the controller field to be exact because of meta data creation in quite a few areas. However, in the case of a virtually created (dynamic) page where redirects are not occurring, the controller field is not used and the name field is. Therefore, you would not use a controller field for a virtually created page. So, no, you would not destroy another field that serves a completely different and unique purpose. It''s very easy to provide a simple no to a question but before you do, you should understand what you are saying no to. -- 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.
Marnen Laibow-Koser
2010-Jan-13 21:45 UTC
Re: Multiple validations on a field... grouping them? only
Alpha Blue wrote:> Marnen Laibow-Koser wrote: >> Bad example. The only time you should ever need to do this is in the >> case already covered by validates_confirmation_of. If you have two >> fields in the DB that should always be identical, then remove one of >> them. >> > > I''m sorry, but I have to disagree. In the case my example, I referred > to an example of virtual pages versus hard controller pages. In the > case of matching fields, if a controller redirect occurs to a statically > created page, I want the name field and the controller field to be exact > because of meta data creation in quite a few areas. However, in the > case of a virtually created (dynamic) page where redirects are not > occurring, the controller field is not used and the name field is. > Therefore, you would not use a controller field for a virtually created > page.What do you mean by "hard controller pages"? If I understand correctly, I think you are making an artificial distinction that is impeding your design decisions.> So, no, you would not destroy another field that serves a > completely different and unique purpose.If the two fields serve independent, unique purposes, then they will contain different data some of the time. If they can never, ever contain different data, then they are ipso facto not independent and should be merged. It''s that simple.> > It''s very easy to provide a simple no to a question but before you do, > you should understand what you are saying no to.I do. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- 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.
Alpha Blue
2010-Jan-14 02:14 UTC
Re: Multiple validations on a field... grouping them? only
Marnen Laibow-Koser wrote:> > If the two fields serve independent, unique purposes, then they will > contain different data some of the time. If they can never, ever > contain different data, then they are ipso facto not independent and > should be merged. > > It''s that simple. >The two fields serve independent, unique purposes, and they contain different data. The only time I check for validation for exact data is when the page being created calls a redirect to a controller - action. In this case, I require the name and the controller to be exact for too many reasons to explain or to go into this particular topic. The point I was making is that you can''t generalize a topic and correct people on criteria you have no information about. You are making false assumptions. If you saw all of my code you could make an informed reply. Validation is a tricky topic and there are many reasons people create custom validations. The point I was making is that it can be done and to make sure you don''t muddy up the place you put your custom validators. I understand your point on putting it in a module. I disagree but in this case we can agree to disagree on the topic. Thanks. -- 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.
Marnen Laibow-Koser
2010-Jan-14 03:00 UTC
Re: Multiple validations on a field... grouping them? only
Alpha Blue wrote:> Marnen Laibow-Koser wrote: >> >> If the two fields serve independent, unique purposes, then they will >> contain different data some of the time. If they can never, ever >> contain different data, then they are ipso facto not independent and >> should be merged. >> >> It''s that simple. >> > > The two fields serve independent, unique purposes, and they contain > different data. The only time I check for validation for exact data is > when the page being created calls a redirect to a controller - action. > In this case, I require the name and the controller to be exact for too > many reasons to explain or to go into this particular topic.Then in this case, you''re right, a validation makes sense.> > The point I was making is that you can''t generalize a topic and correct > people on criteria you have no information about. You are making false > assumptions. If you saw all of my code you could make an informed > reply.And if you had explained the situation more fully in the first place, I would have been able to do that. :)> > Validation is a tricky topic and there are many reasons people create > custom validations. The point I was making is that it can be done and > to make sure you don''t muddy up the place you put your custom > validators. I understand your point on putting it in a module. I > disagreeWhy do you disagree?> but in this case we can agree to disagree on the topic.But we shouldn''t. If you have a good reason, I''d like to hear it.> > Thanks.Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. --0015174c3ff2064cc9047d1716fe Content-Type: text/plain; charset=ISO-8859-1 -- 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. --0015174c3ff2064cc9047d1716fe--
Alpha Blue
2010-Jan-14 03:33 UTC
Re: Multiple validations on a field... grouping them? only
Marnen Laibow-Koser wrote:> > But we shouldn''t. If you have a good reason, I''d like to hear it. >It''s a personal preference. Some people put custom validators in libs and others do it in initializers. I decided to use initializers more because it makes sense for validators and also because I had originally learned to do so right here: http://guides.rubyonrails.org/activerecord_validations_callbacks.html According to rubyonrails.org right in their activerecord_validations-callbacks they state: ============= QUOTE from rubyonrails.org =================You can even create your own validation helpers and reuse them in several different models. Here is an example where we create a custom validation helper to validate the format of fields that represent email addresses: ActiveRecord::Base.class_eval do def self.validates_as_radio(attr_name, n, options={}) validates_inclusion_of attr_name, {:in => 1..n}.merge(options) end end Simply reopen ActiveRecord::Base and define a class method like that. You’d typically put this code somewhere in config/initializers. ========================================================== Some items don''t need to go into initializers but again, it''s more of an organizational approach to rails and if you can show me 100% that both rubyonrails.org and me are wrong, please do so. Thanks mate. :) -- Posted via http://www.ruby-forum.com/. --0023545307701641e6047d178eca Content-Type: text/plain; charset=ISO-8859-1 -- 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. --0023545307701641e6047d178eca--
Alpha Blue
2010-Jan-14 03:56 UTC
Re: Multiple validations on a field... grouping them? only
ActiveRecord::Base.class_eval do def self.validates_is_exact(*attr_names) options = attr_names.extract_options! validates_each(*(attr_names << options)) do |record, attr_name, value| if record.send( options[:compare_field] ) != value record.errors.add(attr_name, options[:message]) end end true end end ======== Read the post above Marnen, but for thoroughness, I''m supplying the code I have in my initializers folder for validators.rb. This way you can see what I''m doing precisely. Take care mate. -- 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.
Marnen Laibow-Koser
2010-Jan-15 01:44 UTC
Re: Multiple validations on a field... grouping them? only
Alpha Blue wrote:> Marnen Laibow-Koser wrote: >> >> But we shouldn''t. If you have a good reason, I''d like to hear it. >> > > It''s a personal preference. Some people put custom validators in libs > and others do it in initializers. > > I decided to use initializers more because it makes sense for validators > and also because I had originally learned to do so right here: > > http://guides.rubyonrails.org/activerecord_validations_callbacks.html > > According to rubyonrails.org right in their > activerecord_validations-callbacks they state: > > ============= QUOTE from rubyonrails.org =================> You can even create your own validation helpers and reuse them in > several different models. Here is an example where we create a custom > validation helper to validate the format of fields that represent email > addresses: > > ActiveRecord::Base.class_eval do def self.validates_as_radio(attr_name, > n, options={}) validates_inclusion_of attr_name, {:in => > 1..n}.merge(options) end end > > Simply reopen ActiveRecord::Base and define a class method like that. > You’d typically put this code somewhere in config/initializers. > > ==========================================================> > Some items don''t need to go into initializers but again, it''s more of an > organizational approach to rails and if you can show me 100% that both > rubyonrails.org and me are wrong, please do so.Interesting. I wasn''t aware that that was in the guides. My interpretation from reading the guide, however, is that while that may be good for the case described in the guide -- one custom validator only -- you really wouldn''t want to do it for anything more involved. I think having long initializer files is probably a code smell in most cases. Frankly, I think even for one custom validator this is probably a bad idea. I think whoever wrote that part of the guides really dropped the ball, unless he or she was simply trying for initial simplicity without elegance. Also, I think you''re cookbooking the guides a little too much -- that is, taking their solutions as gospel even for cases they didn''t really consider. You''ll note that the guide never mentions the case of multiple validators. Remember, sample code is just that -- sample code, not scripture. In short: I see good reasons *not* to do it the way the guide does -- it''s sloppy and duplicates Ruby''s module system for no good reason. I see not a single good reason to do it the way the guide does. Do you have such a reason, other than "because the guide says so"?> > Thanks mate. :)Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. --00032555412ad61df2047d2a251c Content-Type: text/plain; charset=ISO-8859-1 -- 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. --00032555412ad61df2047d2a251c--