I'd like to add something, and I'll include some potentially useful code 
so hopefully my two cents is 'paid for'.

You've given example use cases in which you need a record in the 
database to be 'invalid', temporarily.  Is it possible that your 
validations not covering a particular (exceptional) case?  For example, 
suppose a field is required EXCEPT in a certain condition.  One case 
that comes to mind is when the record represents a document that a user 
can save in an incomplete state, returning later to complete it.  It 
might be allowable for some fields to be nil when the document is 
incomplete.

Using update_attribute to accommodate this seems, to me, to discourage a 
full elaboration of validations.  This is particularly troubling to me 
for two reasons:

1) Rails takes a dim view of database constraints, so model probably 
bears more responsibility for overall system integrity than it would in 
other frameworks.

2) Rails (rightly) insists on MVC, yet methods like update_attribute 
diminish one of the best things about the 'M' - the domain-driven 
approach in which 'model' really means 'a model of the business/domain'. 
I would prefer to see an option on Rails, perhaps 
config.strict_validation, that could be used by those of us who want to 
be able to rely on the model classes in this way.

So, if config.strict_validation == true, we could run the following on 
startup:

# Adds update_attribute!, which incurs validation, and
# issue warnings for use of methods that either bypass or
# don't throw exceptions on validation failure.
module ActiveRecord
  class Base

    # Incurs validation.
    def update_attribute!(name, value)
      send(name.to_s + '=', value)
      save!
    end

    def update_attribute_with_warning(name, value)
      ActiveRecord::Base.validation_warning(:update_attribute)
      update_attribute_without_warning(name, value)
    end

    alias_method_chain :update_attribute, :warning

    private

    # Produce a warning encourage update_attribute! use
    # and listing the line from which it was called.
    def self.validation_warning(method_name)
      # Don't warn about calls from this file or active_record...
      unless caller[1] =~ /activerecord/
        msg=<<EOM
warning: The method '#{method_name}' bypasses validation. Consider 
'#{method_name}!'.
#{method_name} was called from #{caller[1]}
EOM
        warn msg
      end
    end
  end
end

In my own project, I also warn on save, update_attributes and create.

Thanks,

Brian Hartin
brian.hartin@(The free email system by Google).com
-- 
Posted via http://www.ruby-forum.com/.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to