How to update partial attributes of a object from a form?

Nanyang Zhan wrote:

The problem is when I update one group of attributes using: @user.update_attributes(params[:user]) now, because the params[:user] hash only contains partial attributes that @user has, so this can't work.

update_attributes does not require all attributes to be in the hash you pass to it. It will just update whatever attributes you provide and leave the others alone.

Jeff softiesonrails.com

What I don't understand is why Rails writes the whole row when you call update_attributes. Why can't it just update the attributes that you pass in? Any enlightenment on this?

Jeff wrote:

Nanyang I would suggest locking down the possible validation modes
inside your model.

Thus, add a validation instance method like 'strict_validation', and
then key on this inside the validation checks.

validates_presence_of :city, :if => Proc.new {|model| ! model.strict_validation?}

and in your controller,

my_model = Model.new my_model.strict_validation = true

....

keeping the controller thin, and standardizing the models operation.

(the above is pretty loose code, but hopefully demonstrates the idea)

Cheers, Jodi General Partner The nNovation Group inc. www.nnovation.ca/blog

(Nanyang, I've read back through the thread, so I hope the following
will work).

Basically you'll want to set 3 varieties of validation. and within
your User model you'll an instance method to indicate the validation
you require.

within the controller (you may need 1 controller per type of
validation, or a way to figure out what validation method you'll use):

user = User.new(params[:user]) user.set_validation(User::GENERAL_INFO) #see model below [or
User::PERSONAL_INFO), User.set_validation(User::CONTACT_INFO] if user.valid?    user.save else    #deal with the validation error end

and within your model, define the constants (validation methods,
actual validations, et al.)

class Users < ActiveRecord::Base

validates_presence_of :city, :if => Proc.new {|model| ! model.
contact_info_validation?}

   GENERAL_INFO = 1    PERSONAL_INFO = 2    CONTACT_INFO = 3

def set_validation(means)    @validation_means = means end

def contact_info_validation?    @validation_means == User::CONTACT_INFO end

The above syntax isn't tested, so take the approach run with it.

Note: others with more Ruby Fu may recommend better ways to manage
constants (maybe as symbols), but this approach in general will scale
your requirements well.

Cheers, Jodi General Partner The nNovation Group inc. www.nnovation.ca/blog