#272 ✓resolved
Ben Erickson

Invalid resources still save

Reported by Ben Erickson | May 11th, 2008 @ 01:25 AM

Though validations are recognized on a resource (foo.valid? is false and foo.errors is populated with the failed validation errors), the resource is still able to be saved successfully. An additional strange behavior is that the invalid properties are magically transformed to be valid after the save. For example, validates_length :foo, :maximum => 10 where foo is length 13 will reload from the database after a save and be truncated to length 10.

Even resources that should fail at the DB level (columns cannot be NULL but the respective property is set to nil) still save successfully. After saving, the invalid properties are converted to a valid state. Meaning, something that was nil and saved to a DB column that could not be NULL comes back as empty string.

Comments and changes to this ticket

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) May 11th, 2008 @ 01:59 AM

    • State changed from “new” to “open”
    • Assigned user set to “Dan Kubb (dkubb)”

    Ben, I know about the first case, but can you provide a failing spec and example model for the second problem about NOT NULL DB columns being saved as empty strings?

    Even though validation isn't stopping save() on invalid resources, that still should not happen due to the way auto_migrate sets up the tables so that properties with nullable => false are setup as NOT NULL in the DB.

    It would also be good to know which adapter and database version you are using too. Also, are you using auto_migrate to set up your database tables?

  • Ben Erickson

    Ben Erickson May 11th, 2008 @ 12:03 PM

    I attached a test model and spec that show the bug.

    auto_migrate sets up the tables correctly, see below, brand field can't be NULL:

    mysql> show fields from bicycles;
    | Field       | Type        | Null | Key | Default | Extra          |
    | id          | int(11)     | NO   | PRI | NULL    | auto_increment | 
    | brand       | varchar(50) | NO   |     |         |                | 
    | description | text        | YES  |     | NULL    |                | 
    3 rows in set (0.00 sec)

    I'm using the mysql adaptor and the following versions of everything:

    > mysql --version
    mysql  Ver 14.12 Distrib 5.0.45, for apple-darwin9.2.2 (i686) using  EditLine wrapper
    dm-validations (0.9.0)
    do_mysql (0.9.0)
    data_objects (0.9.0)
    dm-core (0.9.0)
    merb_datamapper (0.9.3)

    Usually I use "rake dm:db:automigrate" but I also use DataMapper.auto_migrate! occasionally if I am already in merb-irb. Not sure if one is better or not, I guess I assumed they were equivalent.

    Let me know if you need anything else.

  • Ben Erickson

    Ben Erickson May 11th, 2008 @ 12:03 PM

    Here is the separate bicycle.rb file.

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) May 14th, 2008 @ 09:49 AM

    • Milestone cleared.

    I do believe MySQL will make a field an empty string when it is defined as NOT NULL, and you insert a NULL value. Its weird I know, but one of the quirks with working on MySQL.

    There is a way to make MySQL enforce this constraint though, set the sql_mode configuration variable in your my.cnf configuration file to include "strict_all_tables". Here is the sql_mode that I use:

    sql-mode = ansi_quotes,error_for_division_by_zero,no_auto_create_user,no_auto_value_on_zero,no_dir_in_create,no_engine_substitution,no_unsigned_subtraction,no_zero_date,no_zero_in_date,only_full_group_by,pipes_as_concat,real_as_float,strict_all_tables

    This is pretty much the strictest settings I can make MySQL follow. It really helps for debugging to have these turned on because they help you catch alot of problems before moving code into production. You can find more information about what these mean here:


    Still though, your spec does show one problem, in that resources with the same id are not showing up as equal. Not only should they be equal, but if you compared their object_id values, those should be identical too. I'll look into this problem and post my results in this ticket.

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) May 25th, 2008 @ 09:40 PM

    • State changed from “open” to “resolved”

    I updated dm-validates so that resource will automatically be validated within the :default context if a context is not provided to Resource#save as an argument. This fixes arguably one of the most asked-about issues, while still allowing full contextual validation for those that need it.

    Here is the commit: Added automatic validations on save

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) May 25th, 2008 @ 09:42 PM

    I should also note that the issue I was wondering about with the IdentityMap (IM) not working, I should mention that a repository block was not being used; and the behavior of IM is consistent with it's design -- it would be impossible to offer a "global" IdentityMap for use outside of repository blocks because cached resources would quickly fill up memory on longer running processes.

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

People watching this ticket