[Nitro] Validations, was re: 0.26.0 preview

Bryan Soto bryan.a.soto at gmail.com
Sun Dec 18 16:09:29 EST 2005


Hi,

I had some time last night, so I came up with two options for pending
release.

Option 1, add_unique_error_msgs adds only unique error messages to the
errors list for the field. Validations size still increases (in debug mode
only due to auto-reload), but error messages list doesn't contain multiple
copies of the same message.

Option 2, validation_key converts validations list to a hash and creates a
key object. Validations size doesn't increase but is a bit of a bigger
change.

Both pass unit tests (at least the ones that run. I'm not able to complete
the one's for og).

Anyone want to give them a try for testing purposes?

bryan

On 12/16/05, Bryan Soto <bryan.a.soto at gmail.com > wrote:
>
> <code>
>
> require 'nitro'
> require 'og'
> require 'user'
>
> require 'dev-utils/debug'
>
> Og.setup
>
> class ValidationTest
>   def index
>     out = "The number of validations for User is #{User.validations.length}.<br
> />"
> <http://?&ik=37557988fd&view=cv&search=inbox&th=10833d5b7fe32fdf&lvp=0&cvp=1&qt=&zx=4q1vmgtsqiw9#>
>     u = User.new
>     u.username = 'bryan'
>     u.password = 'bryan'
>     if u.valid?
>       u.save
>     else
>       out << "<br />#{u.errors.errors.inspect}<br />"
>     end
>     out
>   end
> end
>
> Nitro.run ValidationTest
>
> </code>
>
> Run against gems and dev version.
>
> Touch user.rb. Await reload message on console, then refresh browser.
>
> Notice how in gem version, the number of validations increases, but the
> number of errors remains unchanged.
>
> Repeat using dev version. Notice that the number of validations increases
> as well as the number of error message entries.
>
> Basically, the gem version evals the code _once_ in eval_validate
> (glue/lib/validations.rb) the first time #valid? is called, so it ignores
> the repeated validations.
>
> Hope this clears things up as too what I'm talking about. I need to brush
> up on my communication skills. It all made sense to me every single time I
> wrote 8^).
>
> --
>
> As too future design, I was thinking something more like:
>
> <code>
>
> class ValidationKey
>   attr_reader :validation
>   attr_reader :field_name
>
>   def initialize(val, field)
>     @validation, @field_name = val.to_s, field.to_s
>   end
>
>   def hash
>     "#{@validation}-#{@field_name}".hash
>   end
>
>   def ==(other)
>     self.validation == other.validation and self.field_name ==
> other.field_name
>   end
> end
>
> vk = ValidationKey.new(:validate_unique, :username)
>
> validations[vk] = validate_unique_proc_goes_here
>
> </code>
>
> as the key and the proc as the value in the hash. Then the new key would
> just overwrite the old. No more duplicate entries.
>
> And as for application level validations, I was thinking someone with a
> shopping cart might have written their own validate_credit_card_number. Or
> validate_password, where password requires at least one number. Basically,
> some sort of validation that only makes sense in their particular
> application. Though I suppose most people just use aspects for that.
>
> bryan
>
> On 12/16/05, Brian Bugh <brian at xsi-design.com > wrote:
> >
> > I'm not sure I understand what you mean.  The new code is functionally
> > identical to the old way, only it's using blocks and Proc objects
> > instead of using eval. Try this simple Nitro app with both the old and
> > new code:
> >
> >   require 'nitro'
> >   require 'og'
> >   require 'user'
> >
> >   Og.setup
> >
> >   class ValidationTest
> >     def index
> >       "The number of validations for User is
> > #{User.validations.length}."
> >     end
> >   end
> >
> >   Nitro.run ValidationTest
> >
> > Check it in the browser, and it will say 2, then touch user.rb and it
> > will say 4.  The old way basically copy and pasted code into a function,
> > whereas now that code is a list of anonymous methods in an array that is
> >
> > iterated.  That array is only iterated when validate or valid? is called
> > - the same times as the long function was called before.  Hopefully that
> > helps clarify the issue for you.
> >
> > --
> >
> > I have thought about your suggestion, and I think it is a possibility.
> > Do you mean only store the validation list and each field like this:
> >
> >   {:validate_unique => [:username], :validate_value => [:password]}
> >
> > If so, how would we determine what a validation code block was?   One
> > option is to have a list of private instance methods (like
> > validate_values) that check the fields in question, but I am not sure if
> > having one function to declare it and one function to check it is ideal.
> > The names could be confusing because of their similarity.  Using a
> > hashed set like that could possibly move the validation logic solely to
> > when valid? is called, rather than when the validation is first
> > declared.  I like the idea and will try to think of some solutions.
> >
> > By the way, what are application level validations?  Nitro application
> > or Og/Glue?  I am not familiar at all with Nitro, because the project
> > I'm doing that got me interested in Og in the first place doesn't use
> > anything else.
> >
> > Brian B.
> >
> >
> > On Thu, 2005-12-15 at 23:20 -0800, Bryan Soto wrote:
> > > Interesting... I guess noone ever noticed since the code was eval'd on
> > > the first call made to #valid? in the previous implementation. The
> > > array was only iterated through when defining validate(). Now it's
> > > being iterated through on every call.
> > >
> > > Perhaps if, instead of an array, validations were stored in a hash
> > > with the key consisting of the validation type and field name, it
> > > would avoid the duplication and performance hit? It might make
> > > application level validations a bit more complicated, though I'm not
> > > sure if anyone actually uses them. Does anyone?
> > >
> > > On 12/15/05, Brian Bugh < brian at xsi-design.com> wrote:
> > >         Ah, I see.  The current release gem package does this as well,
> >
> > >         so it's a
> > >         general issue with the way validations are handled.  I'm
> > >         innocent! ;)
> > >
> > >         I've tested with extend_object and append_features methods and
> > >         the
> > >         on_included block, and I can't seem to find a reliable way to
> > >         check if
> > >         the file is being loaded/extended again.  The problem is that
> > >         when it is
> > >         reloaded, the class is just reopened and declared the same way
> > >         it was
> > >         before.
> > >
> > >         Any logic I can think of to add to validations for uniqueness
> > >         checking
> > >         will have a performance penalty in production, even though
> > >         production
> > >         doesn't have the reload issue.
> > >
> > >         I will spend more time on this tomorrow to see if I can find
> > >         a
> > >         easy/quick solution for your upcoming release.
> > >
> > >         Brian B.
> > >
> > >
> > >         On Thu, 2005-12-15 at 13:24 -0800, Bryan Soto wrote:
> > >         > Sorry if I wasn't clear. In debug mode, i.e. webrick, files
> > >         are
> > >         > automatically reloaded on change. I noticed after adding and
> > >         removing a
> > >         > field to test Mysql evolution that my validations had
> > >         increased. Something
> > >         > along the lines of:
> > >         >
> > >         > # user.rb
> > >         > class User
> > >         >   property :username
> > >         >   property :password
> > >         >
> > >         >   validate_unique :username
> > >         >   validate_value :password
> > >         > end
> > >         >
> > >         > User.validations.size   #  => 2
> > >         >
> > >         > # touch user.rb
> > >         >
> > >         > User.validations.size   #  => 4
> > >         >
> > >         > assuming user.rb is a model class in a Nitro application.
> > >         Basically, after
> > >         > the touch is performed, the file is reloaded and the
> > >         validations are added
> > >         > anew to the already existing validations array (speculation
> > >         on my part as to
> > >         > your implementation) in the already existing User class.
> > >         >
> > >         > As I said, it's not that a big a deal. A stop and restart of
> > >         the webrick
> > >         > server clears it up. I just happended to notice twice as
> > >         many error messages
> > >         > as I expected from a form. Just make sure your production
> > >         apps aren't in
> > >         > debug mode.
> > >         >
> > >         > bryan
> > >         >
> >
> >
> > _______________________________________________
> > Nitro-general mailing list
> > Nitro-general at rubyforge.org
> > http://rubyforge.org/mailman/listinfo/nitro-general
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/nitro-general/attachments/20051218/6e2ecee8/attachment.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: add_unique_error_msgs
Type: application/octet-stream
Size: 28651 bytes
Desc: not available
Url : http://rubyforge.org/pipermail/nitro-general/attachments/20051218/6e2ecee8/attachment.obj 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: validation_key
Type: application/octet-stream
Size: 29751 bytes
Desc: not available
Url : http://rubyforge.org/pipermail/nitro-general/attachments/20051218/6e2ecee8/attachment-0001.obj 


More information about the Nitro-general mailing list