update_attribute does not validate?

While using the in place editor, I noticed that none of my validations were firing. Digging around in the docs I found that this is deliberate.

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M000909

This method is overwritten by
the Validation module that’ll make sure that updates made with this
method doesn’t get subjected to validation checks. Hence, attributes
can be updated even if the full object isn’t valid.

In the validations module,

alias_method_chain :update_attribute, :validation_skipping
# Updates a single attribute and saves the record without going through the normal validation procedure.
    # This is especially useful for boolean flags on existing records. The regular +update_attribute+ method

    # in Base is replaced with this when the validations module is mixed in, which it is by default.
    def update_attribute_with_validation_skipping(name, value)
      send(name.to_s + '=', value)
      save(false)

    end

Why would validations be turned off by default when using in place editors? and also why would update_attribute have validation turned off by default with no apparent way of turning it back on?

Can anyone explain this to me please.

Cheers

Sorry to cross post from Rails ML but I did not get any response, and this is really bugging me…

I would guess it's that way because inplace editing should accept
anything you give it and deal with the input as is. How would you
report back a failed validation? An alert?

I'm guessing you probably don't want inplace editing for the text
you're trying to modify and if you do, you should update your logic to
convert any bad data into something that will work for you. An
example being an inplace edit where you input html when it's not
allowed, and you simply remove the "invalid" html on the server side
to make it valid.

Anyway, that's my guess.

Thanx for the feedback.

In general though you don’t write much when using an in_place**.
You use an in_place_edit_for in the controller to setup the methods,
and use in_place_editor_field in the view.

I think more importantly than reporting back that a validation failed,
( at the moment until I work out something) is the fact that there is
no validation performed in the first place.

I could manually declare the methods in the controller but I
don’t want to have to declare validation logic in my in_place editor
methods (view/controller centric). My model should look after
it’s own data.

I guess I could also overwrite update_attribute to use validataion, but
why was validation removed from this method in the first place? I
don’t want to go breaking things…

Cheers

I guess I could also overwrite update_attribute to use validataion, but why
was validation removed from this method in the first place? I don't want to
go breaking things...

Most of the other core guys are in bed right now, but I've never used
the in place editor, and I share your surprise that it deliberately
avoids validation. Perhaps David, Tobi, Thomas or Rick could chime
in? On the other hand, it's been deprecated in trunk, so perhaps
this is a good opportunity for someone to extract it to a plugin and
make it much more robust and feature filled?

Thanx for the feedback… I didn’t realise it was
depricated. That still leaves the issue of update_attribute
though. I guess I’ll wait for other guys. Thanx again for
the feedback.

It will be a plugin eventually, so you can still use it as is, but
you'll have to install a plugin when a later rails version is
released.

The case you're speaking of is partially one reason why it will be a
plugin; too many people want it to do different things and when that
happens the functionality should remain as a plugin for a while (if
not forever).

Does anyone have any thoughts as to why the update_attribute method
does not validate, and has no way to turn validation on?

Cheers

I think having this method NOT validate is useful for the handful of
situations in which you want to update the underlying database even
though the valid object hasn't been fully saved.

Eg,
  model = Model.find(42)
  # do something invalid
  model.update_attribute(:invalid, true) unless model.save

I've never run into a situation where I've needed this, but it's nice
to know it's there. You may want to use Ruby's class rewriting
capabilities to update the in_place_edit_for method to use
#update_attributes (which will do validation checks):

module ActionController
  module Macros
    module InPlaceEditing
      module ClassMethods
        def in_place_edit_for(object, attribute, options = {})
          define_method("set_#{object}_#{attribute}") do
            @item = object.to_s.camelize.constantize.find(params[:id])
            @item.update_attributes({ attribute => params[:value] })
            render :text => @item.send(attribute)
          end
        end
      end
    end
  end
end

Or, you can just write out your own set_* methods.

Daniel N wrote: