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.
# 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?
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.
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…
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).
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.