4

Is there a replacement for update_attribute? I know you can still use it in Rails 3 but you get deprecation messages.

The reason why I need to use update_attribute is because I need to skip validations but run callbacks.

The only way that I've found of doing this (and avoid deprecation messages), is by simply extracting the code from update_attribute:

Object.send("#{attribute}=", value)
Object.save(:validate => false)

I'd like to know if there is another (proper) way of doing this.

Thanks.

Adam Eberlin
  • 14,005
  • 5
  • 37
  • 49
miligraf
  • 1,042
  • 9
  • 22
  • The only way to run callbacks without validations that I have seen is passing `:validate => false` to the save call. That *is* the proper way. If you do not need validations OR callbacks, then you should use `update_column`. If you want to update a lot of records AND skip validations AND skip callbacks, then you want `Model.update_all`. – Brett Bender Oct 17 '12 at 21:34
  • I've updated my answer. I guess now it can help. – ck3g Oct 19 '12 at 06:42

3 Answers3

6

I would suggest what the answer is no.

You cannot pass false to update_attributes to skip validation.

I would recommend you update_column, but this method skip callbacks. And judging by you question it isn't what you need.

Update:

I've found interesting table in that presentation. That I guess can prove my opinion.

update_(attribute|column)s

Judging by this table there is only one method which satisfies the conditions.

ck3g
  • 5,829
  • 3
  • 32
  • 52
1

Would you consider using conditional validation? http://guides.rubyonrails.org/active_record_validations_callbacks.html#conditional-validation

You could set an attribute on the object to disable the validation in question for the current record.

Michael Hellein
  • 4,378
  • 1
  • 25
  • 21
0

From the validations documentation:

The validation process on save can be skipped by passing :validate => false. The regular #save method is replaced with this when the validations module is mixed in, which it is by default.

So simply set your attribute to the correct value and call save with the validates parameter set to false. You do not need to use send, either, unless you have code that relies on metaprogramming, but that is not obvious from your example.

object.attribute = value
object.save(:validate => false)
Brett Bender
  • 19,388
  • 2
  • 38
  • 46
  • I don't understand the downvote here. While it's probably not a good idea to skip validation (unless your validation is wrong*), this is an effective way to skip that step of the persistence workflow. * That's a red flag, to me. Validations are there for a reason! – Michael Hellein Oct 18 '12 at 16:18