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: