Giter Site home page Giter Site logo

dm-validations's Introduction

This is a DataMapper plugin that provides validations for DataMapper model classes.

Setup

DataMapper validation capabilities are automatically available for DataMapper resources when you require dm-validations’ in your application. There is no need to manually include anything, every DataMapper::Resource will be able to handle validations once this gem got required.

Specifying Model Validations

There are two primary ways to implement validations for your models

1) Placing validation methods with properties as params in your class

require 'dm-core'
require 'dm-validations'

class ProgrammingLanguage
  include DataMapper::Resource
  property :name, String
  validates_presence_of :name
end

2) Using auto-validations, please see DataMapper::Validation::AutoValidations. Note that not all validations that are provided via validation methods, are also available as autovalidation options. If they are available, they’re functionally equivalent though.

class ProgrammingLanguage
  include DataMapper::Resource
  property :name, String, :required => true
end

See data_mapper/validation/macros.rb for to learn about the complete collection of validation rules available.

Validating

DataMapper validations, when included, alter the default save/create/update process for a model. Unless you specify a context the resource must be valid in the :default context before saving.

You may manually validate a resource using the valid? method, which will return true if the resource is valid, and false if it is invalid.

Working with Validation Errors

If your validators find errors in your model, they will populate the DataMapper::Validation::ViolationSet object that is available through each of your models via calls to your model’s errors method.

For example:

my_account = Account.new(:name => "Jose")
if my_account.save
  # my_account is valid and has been saved
else
  my_account.errors.each do |e|
    puts e
  end
end

See DataMapper::Validation::ViolationSet for all you can do with your model’s errors method.

Contextual Validation

DataMapper Validation also provide a means of grouping your validations into contexts. This enables you to run different sets of validations when you need it. For instance, the same model may not only behave differently when initially saved or saved on update, but also require special validation sets for publishing, exporting, importing and so on.

Again, using our example for pure Ruby class validations:

class ProgrammingLanguage

  include DataMapper::Resource

  property :name, String

  def ensure_allows_manual_memory_management
    # ...
  end

  def ensure_allows_optional_parentheses
    # ...
  end

  validates_presence_of :name
  validates_with_method :ensure_allows_optional_parentheses,     :when => [:implementing_a_dsl]
  validates_with_method :ensure_allows_manual_memory_management, :when => [:doing_system_programming]
end

ProgrammingLanguage instance now use #valid? method with one of two context symbols:

@ruby.valid?(:implementing_a_dsl)       # => true
@ruby.valid?(:doing_system_programming) # => false

@c.valid?(:implementing_a_dsl)       # => false
@c.valid?(:doing_system_programming) # => true

Each context causes different set of validations to be triggered. If you don’t specify a context using :when, :on or :group options (they are all aliases and do the same thing), default context name is :default. When you do model.valid? (without specifying context explicitly), again, :default context is used. One validation can be used in two, three or five contexts if you like:

class Book

  include ::DataMapper::Resource

  property :id,           Serial
  property :name,         String

  property :agreed_title, String
  property :finished_toc, Boolean

  # used in all contexts, including default
  validates_presence_of :name,         :when => [:default, :sending_to_print]
  validates_presence_of :agreed_title, :when => [:sending_to_print]

  validates_with_block :toc, :when => [:sending_to_print] do
    if self.finished_toc
      [true]
    else
      [false, "TOC must be finalized before you send a book to print"]
    end
  end
end

In the example above, name is validated for presence in both :default context and :sending_to_print context, while TOC related block validation and title presence validation only take place in :sending_to_print context.

dm-validations's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

dm-validations's Issues

drop dm-core dependency?

Hello, I'm wondering is it possible and makes sense to make dm-validations independent from dm-core and applicable to any Ruby object?

For example - I created Object Model for MongoDB (http://alexeypetrushin.github.com/mongodb_model) , and because I don't want to make it ActiveModel dependent I has to use another validation gem.

But right now there's no any library that provide abstract validation support for pure ruby objects. So I took the old validatable gem and throw out all ActiveModel dependent stuff from there (https://github.com/alexeypetrushin/validatable2).

But why do we have to do the same work twice? Maybe it's make sence to create abstract gem for validations without any dependencies and use it in any project?

For example remove dm-cored dependency from dm-validations, so I (and others) can use it also in other projects and commit to it and make it better?

What do You think?

Numeric validator precision/scale validation fails for certain floats on MRI 1.9.3

In validators/numeric_validator.rb on line 38

      def value_as_string(value)
        case value
          # Avoid Scientific Notation in Float to_s
          when Float      then value.to_d.to_s('F')
          when BigDecimal then value.to_s('F')
          else value.to_s
        end
      end

Given: f=-75.6942185

We call, f.to_d.to_s('F')

On all rubies except 1.9.3 we get:

"-75.6942185"

On MRI 1.9.3 we get:

"-75.69421850000001"

When then causes the validator to report an invalid precision/scale

utf-8 problem with regex match

Many times I have users submitting mails with special accents like pelé@gmail.com and dm-validations instead of returning true or false raises the exception "incompatible encoding regexp match (ASCII-8BIT regexp with UTF-8 string)"
http://pastebin.com/StQSp7eB

Any solution to this?

I'm using dm 1.0.2, ruby 1.9.1 with the following properties:
property :email, String
validates_format_of :email, :with => :email_address

someone on IRC told me to add an "u" at the end of the regex match on line 41, but it also didn't work
https://github.com/datamapper/dm-validations/blob/master/lib/dm-validations/formats/email.rb

dm-validations causes lazy-loaded attributes to load one at a time

Simply including 'dm-validations' will add auto-validations for many standard property types. When the validations run, each validator operates on the property it applies to, and that property is loaded if not already (i.e. lazy).

The problem is that most standard property types get at least one auto-validation, so saving/updating objects with many/large lazy properties ends up defeating the value of lazy-loading to begin with, compounding the # of SQL queries for updating to 1 + # of lazy loaded properties.

Here is a demo & patch that "partially" solves the issue by loading all the attributes of fields-to-be-validated all in one shot, before the validators run. At the very least, it demonstrates the issue.

https://gist.github.com/5b7effb4cf5f737aa28e

After talking with dkubb, it might make more sense to just not fire the validators on attributes that aren't dirty/not-loaded, thereby reducing the overall CPU cost of saving/updating the models to begin with.


Created by Jordan Ritter - 2009-10-21 16:31:41 UTC

Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1100

Custom error messages for all inferred validations

I would like to use custom error messages for all inferred validations.
What I want to do is shown in this spec (based on this):

 it "should have correct error messages" do
    custom_boat = Class.new do
      include DataMapper::Resource

      def self.name
        'Boat'
      end

      property :id,   DataMapper::Property::Serial
      property :length, Integer, :min => 1,
               :messages => {
                 :greater_than_or_equal_to => "Length must be at least 1"
               }
     end

    boat = custom_boat.new

    boat.length = 0
    boat.should_not be_valid
    boat.errors.on(:length).should == [ 'Length must be at least 1' ]

    boat.length = 3
    boat.should be_valid
    boat.errors.on(:length).should be_nil

As you can see I would like to override the default error message for the auto validation derived from :min => 1.
Currently this spec fails:

'Inferred validations should have correct error messages' FAILED
expected: ["Length must be at least 1"],
     got: [#<DataMapper::Validation::Violation @resource=#<Boat @id=nil @name="superboat" @length=0> @rule=#<Dat
aMapper::Validation::Rule::Numericalness::GreaterThanOrEqual @attribute_name=:length @allow_nil=true @allow_blan
k=nil @custom_message=nil @if_clause=nil @unless_clause=nil @expected=1> @custom_message=nil @attribute_name=:le
ngth>] (using ==) 

Is there a good reason why boat.errors does not get a string attached due to the failed validation but this Violation instance instead? Does it make sense to change that?

I would love to provide a pull request if you think this change makes sense.

ValidatesUniqueness mismatches the implementation of unique indexes in dm-constraints

Given a model

class Foo
  property :num1, Integer, :unique => :scope_name
  property :num2, Integer, :unique => :scope_name
  belongs_to :bar, :unique => :scope_name
end

This example results into a perfectly working unique index "unique_foos_scope_name" with three fields ('num1', 'num2' and 'bar_id'). But the validation won't work and would throw the following exception:

raise(ArgumentError,"Could not find property to scope by: #{subject}. Note that :unique does not currently support arbitrarily named groups, for that you should use :unique_index with an explicit validates_uniqueness_of.")

Following the instructions from the exception this would lead to the following model:

class Foo
  property :num1, Integer
  property :num2, Integer, :unique => [:num1, :bar]
  belongs_to :bar
end

Now the Validation is working but the generated indexes are crap (unique index with only one field: 'num2').

The only solution to fix this would be to address the constraints separately:

class Foo
  property :num1, Integer, :unique_index => :index_name
  property :num2, Integer, :unique => [:num1, :bar], :unique_index => :index_name
  belongs_to :bar, :unique_index => :index_name
end

But this also breaks the application because belongs_to can't handle the :unique_index option correctly. So you'll have to use:

class Foo
  property :num1, Integer, :unique_index => :index_name
  property :num2, Integer, :unique => [:num1, :bar], :unique_index => :index_name
  belongs_to :bar
  property :bar_id, :unique_index => :index_name, :index => true
end

This seems to work but I don't think this is what the most people want :-)

Patch 1.2.0 to play nicely with Formtastic

Formtastic is able to infer from ActiveRecord models which fields are required and mark them with an asterisk. It is not able to do this with DM 1.2.0. (marks all fields as required). However, the following monkeypatch makes it work in our app.

What would be the best way to contribute this, given that you're now working on 1.3.0 and 2.0?

module DataMapper::Validations::ClassMethods
  def validators_on(attribute)
    validators[attribute.to_sym] || []
  end
end

class DataMapper::Validations::GenericValidator
  def self.kind
    @kind ||= name.split('::').last.sub(/Validator$/, '').downcase.to_sym
  end

  def kind
    self.class.kind
  end
end

validates_presence_of doesn't expect a space

Using validates_presence_of(:description), I'm getting this error:

Expected errors to include "Description must not be blank" when description is set to nil, got errors: ["Description must not be blank "]

The only difference between the expected and actual error is a space at the end.

Note that if I write my own validation, the actual error message doesn't have a space at the end.

it "should validate the presence of description" do
  @robot.description = nil
  @robot.valid?
  @robot.errors.full_messages.should include("Description must not be blank")
end

How can I either cause the error not to have a space or specify the expected message as having one?

Regexp issue with ruby 1.9.3-preview1

/home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/dm-validations-1.1.0/lib/dm-validations/formats/email.rb:41:in `<module:Email>': invalid character property name {Lu}: /^(?:[a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+([.][a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]*)+|["](?:[^\x01-\x08\x11\x12\x14-\x1f\x7f\x0d\x22\x5c]|(\x5c[\x01-\x09\x11\x12\x14-\x7f]))+["]|(?:[a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+|["](?:[^\x01-\x08\x11\x12\x14-\x1f\x7f\x0d\x22\x5c]|(\x5c[\x01-\x09\x11\x12\x14-\x7f]))+["])([.](?:[a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+|["](?:[^\x01-\x08\x11\x12\x14-\x1f\x7f\x0d\x22\x5c]|(\x5c[\x01-\x09\x11\x12\x14-\x7f]))+["]))*)@(?:[a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+([.][a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]*)+|\[(?:[\x01-\x08\x11\x12\x14-\x1f\x7f\x21-\x5a\x5e-\x7e]|(\x5c[\x01-\x09\x11\x12\x14-\x7f]))+\]|[a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+([.][a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+)+)$/ (RegexpError)
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/dm-validations-1.1.0/lib/dm-validations/formats/email.rb:6:in `<module:Format>'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/dm-validations-1.1.0/lib/dm-validations/formats/email.rb:5:in `<module:Validations>'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/dm-validations-1.1.0/lib/dm-validations/formats/email.rb:4:in `<module:DataMapper>'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/dm-validations-1.1.0/lib/dm-validations/formats/email.rb:3:in `<top (required)>'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/dm-validations-1.1.0/lib/dm-validations/validators/format_validator.rb:4:in `require'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/dm-validations-1.1.0/lib/dm-validations/validators/format_validator.rb:4:in `<top (required)>'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/dm-validations-1.1.0/lib/dm-validations.rb:41:in `require'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/dm-validations-1.1.0/lib/dm-validations.rb:41:in `<top (required)>'
    from /home/carl/code/vetcloud/lib/models.rb:5:in `require'
    from /home/carl/code/vetcloud/lib/models.rb:5:in `<top (required)>'
    from /home/carl/code/vetcloud/lib/auth.rb:4:in `require'
    from /home/carl/code/vetcloud/lib/auth.rb:4:in `<top (required)>'
    from /home/carl/code/vetcloud/config.ru:4:in `require'
    from /home/carl/code/vetcloud/config.ru:4:in `block (2 levels) in <main>'
    from /home/carl/code/vetcloud/config.ru:4:in `each'
    from /home/carl/code/vetcloud/config.ru:4:in `block in <main>'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/rack-1.3.1/lib/rack/builder.rb:51:in `instance_eval'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/rack-1.3.1/lib/rack/builder.rb:51:in `initialize'
    from /home/carl/code/vetcloud/config.ru:1:in `new'
    from /home/carl/code/vetcloud/config.ru:1:in `<main>'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/thin-1.2.11/lib/rack/adapter/loader.rb:36:in `eval'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/thin-1.2.11/lib/rack/adapter/loader.rb:36:in `load'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/thin-1.2.11/lib/rack/adapter/loader.rb:45:in `for'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/thin-1.2.11/lib/thin/controllers/controller.rb:169:in `load_adapter'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/thin-1.2.11/lib/thin/controllers/controller.rb:73:in `start'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/thin-1.2.11/lib/thin/runner.rb:185:in `run_command'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/thin-1.2.11/lib/thin/runner.rb:151:in `run!'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/gems/thin-1.2.11/bin/thin:6:in `<top (required)>'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/bin/thin:19:in `load'
    from /home/carl/.rvm/gems/ruby-1.9.3-preview1/bin/thin:19:in `<main>'

Custom messages append instead of override

When you declare a property twice, and specify a custom message the second time, it gets appended to the default English message, instead of replacing it.

# In the dm-tags gem
class Tag
  property :name [...]
end

# In my user model
class Tag
  property :name, String, :required => true, :unique => true, :length => 50,
           :messages => { :length => "Le nom est trop long (50 caractères max)." }
end

# Result when validation fails (:name too long)
=> "Name must be at most 50 characters longLe nom est trop long (50 caractères max)."

Created by lwouis - 2010-09-18 16:45:35 UTC

Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1415

Better localizability for dm-validations

I want to revise the issue of localization again because it has been one of the pain points for me in using datamapper; and the last (and only?) ticket I could find on this issue is several years old and closed.

dm-validations allows changing the error messages, but that's of little use without the ability to translate model and field names. It also doesn't integrate nicely e.g. into Rails.

There are different ways to achieve this, but I think it would be good if dm-validations would be language-agnostic. For example instead of generating an error message immediately when adding an error, add information about the violation: the resource, field name, failed validation and validation-specific context values (user object, :password, :too_short, :minimum => 6).

With such an approach it would be easy to put different ways of translation on top of it, e.g.

  • a default implementation when using dm-validations stand-alone,
  • dm-rails can tie it into the i18n part of Rails.

Custom messages can be added as additional context information (my fork of dm-validations does that), though with the suggested localizability these would maybe become a bit superfluous.


Created by gix - 2011-01-29 20:03:11 UTC

Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1477

String, :length => 3..100 isn't requiring that the string is not blank

unless of course you add :required => true to it.

require 'dm-core'
require 'dm-validations'
DataMapper::Logger.new($stdout, :debug)

# A MySQL connection:
DataMapper.setup(:default, 'mysql://localhost/ap')

class User
  include DataMapper::Resource  
  property :id, Serial
  property :name, String, :length => 3..20
end

class Topic
  include DataMapper::Resource    
  property :id, Serial
  property :subject, String, :length => 3..20 #, :required => true
  belongs_to :user
end  

DataMapper.finalize

t = Topic.new 'user' => User.first
t.valid?
puts t.errors.to_hash

-> says its valid, when it shouldn't be.


Created by Kevin Watt - 2010-07-19 21:21:17 UTC

Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1369

Different error messages for related resource save fails

I have this setting enabled: DataMapper::Model.raise_on_save_failure = true

Spent several hours on a problem today whereby a resource wasn't saving and I couldn't figure out why. Turns out a parent resource was have some validation troubles (thanks to a custom validation gone bad) but the only error I got was "DataMapper was unable to save the resource" or some jazz like that. I think it would be supremely useful if a validation save aborts due to a related resource validation failure that a different error be thrown which lists the offending resource. Could save other developers a ton of time and also hair from being pulled out.

Date fields coerces invalid dates into valid dates which then passes validation

When using (for example) this property in the model:

 property :birthday, Date, required: true
 validates_primitive_type_of :birthday

and f.date_select :birthday, start_year: Time.now.year, end_year: 1900, prompt: true in the view, Rails/DM will change an invalid date like Year=nil, Day=nil, Month=11 to 0001-11-01, which then passes validation. It's not possible to do a manual validation, since you don't get the raw data in the model.
Only if all of the date parameters birthday(1i), birthday(2i), birthday(3i) is nil will validation fail.

Raising exception when saving instead of returning true

When I try, by testing, to persist a model to a in-memory sqlite database with a duplicated primary key, it raises a DataObjects::IntegrityError, and the docs says "...datamapper returns true or false for all operations manipulating the persisted state of a resource (#create, #save, #update and #destroy). If you want it to raise exceptions instead, you can instruct datamapper to..."

I checked in my model:
DataMapper::Model.raise_on_save_failure # false
Zoo.raise_on_save_failure # false
zoo.raise_on_save_failure # false

So, how can I get the expected default behaviour?

save method not catching validations on attr_accessors

It seems as though :save will not catch any validations errors if no DM properties were modified, but :valid? will. Is this the correct behavior? For example:

class TestDM
  include DataMapper::Resource

  property :id, Serial
  property :name
  attr_accessor :password

  validates_with_block do
    @password.blank? || @password.length >= 8 ? true : [false, "Password must be at least 8 characters"]
  end
end

Create a new TestDM:

> test = TestDM.new
> test.name = "ted"
> test.save
true

Find that last TestDM and add an invalid password (too short) and save. It should be false, but it returns true instead.

> test = TestDM.last
> test.password = "asdf"
> test.save
true

Do the same thing, but check valid? instead of save. This works as expected.

> test = TestDM.last
> test.password = "asdf"
> test.valid?
false

Do the same thing, but change any DM property and save. This works as expected.

> test = TestDM.last
> test.password = "asdf"
> test.name = "teddy"
> test.save
false

The implications of this are that all of my controller methods need to do:

if @test.valid?
  @test.save
  ...
else
  ...
end

which is not as nice as you would normally do it. Thoughts?


Created by tedkimble - 2010-12-24 06:17:20 UTC

Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1372

validates_with_block is broken when passing in an option hash

in lib/dm-validations/validators/block_validator.rb:53

options = fields.last.is_a?(Hash) ? fields.last.pop.dup : {}

It seems the intention is actually

 options = fields.last.is_a?(Hash) ? fields.pop.dup : {}

without last, since Hash does;t have a pop method

Relationships to unsaved objects throw validation error

Say I have a Topic object which has_many :posts, and when I create a Topic, I want to also include an opening Post.

If I assigned a Topic to the Post (or vice versa) without first saving the Topic, post.valid? will return false and post.errors will include "Topic must not be blank". I believe that since the topic relationship is set, post.valid? should return true. (although if the Topic is not saved first, post.save should fail)

A workaround is to use topic.save and handle a false result from that, but I personally prefer to use the valid? methods before saving.

Email problem on 1.9.3.preview1

RegexpError: invalid character property name {Lu}: /^(?:[a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+([.][a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]*)+|["](?:[^\x01-\x08\x11\x12\x14-\x1f\x7f\x0d\x22\x5c]|(\x5c[\x01-\x09\x11\x12\x14-\x7f]))+["]|(?:[a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+|["](?:[^\x01-\x08\x11\x12\x14-\x1f\x7f\x0d\x22\x5c]|(\x5c[\x01-\x09\x11\x12\x14-\x7f]))+["])([.](?:[a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+|["](?:[^\x01-\x08\x11\x12\x14-\x1f\x7f\x0d\x22\x5c]|(\x5c[\x01-\x09\x11\x12\x14-\x7f]))+["]))*)@(?:[a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+([.][a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]*)+|\[(?:[\x01-\x08\x11\x12\x14-\x1f\x7f\x21-\x5a\x5e-\x7e]|(\x5c[\x01-\x09\x11\x12\x14-\x7f]))+\]|[a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+([.][a-zA-Z\p{Lu}\p{Ll}0-9!#$%&'*+\/=?^_`{|}~-]+)+)$/
    /Users/DAddYE/.rvm/gems/ruby-1.9.3-preview1/gems/dm-validations-1.1.0/lib/dm-validations/formats/email.rb:41:in `<module:Email>'
$ gem env
RubyGems Environment:
  - RUBYGEMS VERSION: 1.8.6
  - RUBY VERSION: 1.9.3 (2011-07-31 patchlevel -1) [x86_64-darwin11.2.0]
  - INSTALLATION DIRECTORY: /Users/DAddYE/.rvm/gems/ruby-1.9.3-preview1
  - RUBY EXECUTABLE: /Users/DAddYE/.rvm/rubies/ruby-1.9.3-preview1/bin/ruby
  - EXECUTABLE DIRECTORY: /Users/DAddYE/.rvm/gems/ruby-1.9.3-preview1/bin
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-darwin-11
  - GEM PATHS:
     - /Users/DAddYE/.rvm/gems/ruby-1.9.3-preview1
     - /Users/DAddYE/.rvm/gems/ruby-1.9.3-preview1@global
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :benchmark => false
     - :backtrace => false
     - :bulk_threshold => 1000
     - "gem" => "--no-rdoc --no-ri"
  - REMOTE SOURCES:
     - http://rubygems.org/

require of formats/email and formats/url

format_validator.rb is using a non-standard methodology to reference formats/email and formats/url

require Pathname(FILE).dirname.expand_path + ".." + 'formats/email'
require Pathname(FILE).dirname.expand_path + ".." + 'formats/url'

While this may work in common environments, it does not work when the gem has been packaged in a jar under JRuby.

Isn't validating an association correctly

Given this model for a legacy schema:

class AdminUserNote
  include DataMapper::Resource

  storage_names[:default] = 'usernote'

  property :id,         Sequence,     :field => 'noteid'
  property :user_id,    Integer,      :field => 'userid'
  property :subject_id, Integer,      :field => 'subjectid'
  property :created_at, EpochTime,    :field => 'timecreated'
  property :content,    String

  validates_presence_of :content

  belongs_to :user
  belongs_to :subject, 'User', :child_key => [:subject_id]
end

For some reason, this isn't validating, with the cryptic error message of "Subjectid must not be blank":

def create
  @user = User.get!(params[:user_id])
  @note = AdminUserNote.new({
    :user => active_user,
    :subject => @user,
    :content => params[:content]
  });
  if @note.save
    redirect_to(admin_user_path(@user))
  else
    render :new
  end
end

While this is validating (passing the legacy field name directly):

def create
  @user = User.get!(params[:user_id])
  @note = AdminUserNote.new({
    :user => active_user,
    :subjectid => @user.id, # Nasty hack
    :content => params[:content]
  });
  if @note.save
    redirect_to(admin_user_path(@user))
  else
    render :new
  end
end

It's interesting that it's only the :subject property that falls victim to the bug and that :user works fine (presumably because the key name is predictable).

Unexpected validation failure with decimal properties

I'm seeing an unexpected validation failure with decimal properties. Also, I'm using the release-1.2 branch.

A simple testcase:

class Model
  include DataMapper::Resource
  property :duration, Decimal
end

m = Model.new
m.duration = BigDecimal.new(1.01, 3)
m.save # raises DataMapper::SaveFailureError
m.errors[:duration] # => ["Duration must be a number"]

Can't swap the value of a unique property between two objects

Hopefully the ticket title explains the problem well enough, I'm too tired to go into prose...

This came about with integers, as we were trying to re-implement a simple for of is-list. But I've written an example from scratch to illustrate the problem:

require 'rubygems'

require 'dm-core'
require 'dm-validations'
require 'spec'

SQLITE_FILE = File.join(`pwd`.chomp, "test.db")

DataMapper.setup(:default, "sqlite3:#{SQLITE_FILE}")
DataMapper.setup(:reloaded, "sqlite3:#{SQLITE_FILE}")

class Farm
  include DataMapper::Resource

  property :id, Serial

  has n, :cows, :order => [:cow_id]
end

class Cow
  include DataMapper::Resource

  property :id, Serial
  property :cow_id, Integer
  property :name, String

  # Comment out the following line to make the spec pass
  validates_is_unique :name, :scope => [:farm]

  belongs_to :farm
end

module IdentityMapHelper
  def with_db_reconnect(&blk)
    original_repository = DataMapper::Repository.context.pop
    repository(:reloaded, &blk)
    DataMapper::Repository.context << original_repository
  end
end

Spec::Runner.configure do |config|
  include IdentityMapHelper

  config.before(:each) do
    Farm.auto_migrate!
    Cow.auto_migrate!
  end

  config.before(:each) do    
    DataMapper::Repository.context << repository(:default)
  end

  config.after(:each) do
    DataMapper::Repository.context.pop
  end
end

describe "Renaming a cow" do
  before(:each) do
    @bluebell_farm = Farm.create!
    @cow_1 = Cow.create(:cow_id => 1, :name => "Daisy")
    @cow_2 = Cow.create(:cow_id => 1, :name => "Florence")
    @cow_3 = Cow.create(:cow_id => 1, :name => "Tastyburger")

    @bluebell_farm.cows << @cow_1 << @cow_2 << @cow_3
    @bluebell_farm.save
  end

  it "should let you rename the cows" do
    @cow_1.name = "Florence"
    @cow_2.name = "Daisy"
    @bluebell_farm.save

    with_db_reconnect do
      bluebell_farm_reloaded = Farm.get(@bluebell_farm.id)
      cow_1_reloaded = bluebell_farm_reloaded.cows[0]
      cow_2_reloaded = bluebell_farm_reloaded.cows[1]
      cow_1_reloaded.name.should == "Florence"
      cow_2_reloaded.name.should == "Daisy"
    end
  end
end

Created by Ashley Moran - 2009-06-30 20:08:34 UTC

Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/936

:set option does not work well with Sets

The :set option appears to be designed to only work with Arrays, and not Sets. The :set option should call to_a on all given values, to ensure that the value is compatible.

dm-validations-1.1.0/lib/dm-validations/validators/within_validator.rb:32:in `call': undefined method `join' for #<Set:0xb79dd4d0> (NoMethodError)
    from dm-validations-1.1.0/lib/dm-validations/contextual_validators.rb:104:in `execute'
    from dm-validations-1.1.0/lib/dm-validations/contextual_validators.rb:104:in `map'
    from dm-validations-1.1.0/lib/dm-validations/contextual_validators.rb:104:in `execute'
    from dm-validations-1.1.0/lib/dm-validations.rb:110:in `valid?'
    from dm-validations-1.1.0/lib/dm-validations.rb:81:in `save_self'

.on() creates an empty array in the errors

I do not have any errors on my object. If I call obj.errors I get:

{}

If I do a

obj.errors.on(:attr)

now, I would expect that obj.errors returns the same hash afterwards. It does not though, it returns:

{attr: []}

Is that expected behaviour?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.