tower-archive / tower

UNMAINTAINED - Small components for building apps, manipulating data, and automating a distributed infrastructure.
http://tower.github.io
MIT License
1.79k stars 120 forks source link

set validation: validate as fine if we have null instead of iterable #350

Closed tremby closed 11 years ago

tremby commented 11 years ago

Rationale: now I can skip/abort the validation conditionally such as with the following:

  in: ->
    if @get('country') == 'CA'
      ['ON', 'QC', 'NS', 'NB', 'MB', 'BC', 'PE', 'SK', 'AB', 'NL', 'NT', 'YT', 'NU']
    else
      null

What do you think of this? This functionality would definitely be nice but maybe you have a different idea of how it should be implemented.

lancejpollard commented 11 years ago

How about this:

class App.Address extends Tower.Model
  @validates 'state', in: ['ON', ...], if: 'countryIsCA'

  countryIsCA: ->
    @get('country') == 'CA'

or a lambda/anonymous version:

class App.Address extends Tower.Model
  @validates 'state', in: ['ON', ...], if: -> @get('country') == 'CA'

and maybe even, if in is an array of objects, then this:

class App.Address extends Tower.Model
  @validates 'state', in: [
      value: ['ON', ...], if: 'countryIsCA'
    , value: ['NY', ...], if: 'countryIsUS'
  ]

or this (where if is the key):

class App.Address extends Tower.Model
  @validates 'state', in:
    countryIsCA: ['ON', ...]
    countryIsUS: ['NY', ...]

Or maybe having that sort of DSL is overkill, and just doing it manually is better like what you're suggesting (the more I think about it, it's probably easier this way):

class App.Address extends Tower.Model
  @validates 'state', in: ->
    if @get('country') == 'CA'
      ['ON', 'QC', 'NS', 'NB', 'MB', 'BC', 'PE', 'SK', 'AB', 'NL', 'NT', 'YT', 'NU']
    else
      null
tremby commented 11 years ago

I think if you do think conditional validation is something to add, your third example

class App.Address extends Tower.Model
  @validates 'state', in: [
      value: ['ON', ...], if: 'countryIsCA'
    , value: ['NY', ...], if: 'countryIsUS'
  ]

wins for me. But I think I prefer just returning null from the function if you want to skip the validation. If you accept this suggestion, it would make sense to implement it for all the other validator types too.

Or maybe having the function return a boolean should pass (true) or fail (false) the validation. That could potentially be more useful than just null to skip (pass) it. What seems most intuitive to you?