06 MarActiveRecord.save without callbacks
Saturday, 06 March 2010 — 09:59You already know there is a way to avoid running validations when you save an ActiveRecord
project.save(false)But, what if you want to skip validations?. There are some ways to achieve this. There are some metaprogramming options, such as adding and removing methods, or calling private methods with send (or send!)
project = Project.new(:name => 'ggomeze.com') project.send(:create_without_callbacks) project = Project.find(1) project.send(:update_without_callbacks)
If these methods are private, it just because there should be a different way to do the same, no? :-). So here is my favorite:
# accessors attr_accessor :skip_callbacks # callbacks with_options :unless => :skip_callbacks do |project| project.after_update :do_something project.after_save :do_other_thing end
Ah, just a note, you might be tempted to use this, instead of attr_accessor:
attr_accessor_with_default :skip_callbacks, false
but seems like attr_accessor_with_default creates a class attribute which might be problematic under some circumstances
Ger
06 Mar 15:28
The question, that might seem very innocent,is: why do you want to skip validations. Doesn’t it enforces storing invalid records on the DB?
06 Mar 17:35
There are many cases where you might want to skip validations, usually when you are updating a record. Let’s think on a project who has multiple milestones.
If you create a new project with some milestones, you will use:
milestones.build(attributes)
and the new milestones will be saved at the time you save the project. But if you are editing the project and milestones, you will be doing something like:
milestone.attributes = attributes
but in this case you are updating the project, so they will never get saved. You have to do it “manually”. So you will need an after_update call back for just saving your new milestones. Validations on project and milestones, will take place before that point. Thus, you don’t need to run them twice