13

Is there a way to skip callbacks and validation by doing something along these lines in Rails 3?

Object.save(:validate => false, :skip_callbacks => true)

Thanks!

tokland
  • 66,169
  • 13
  • 144
  • 170
nbucciarelli
  • 460
  • 2
  • 6
  • 16

6 Answers6

15
Object.save(:validate => false)

works as you would expect. So far as I know you cannot turn off callbacks (unless you return false from a before_ callback, but that then aborts the transaction).

baldmark
  • 699
  • 11
  • 23
3

I encountered something like that before and I used this:

Model.send(:create_without_callbacks)
Model.send(:update_without_callbacks)
patsanch
  • 441
  • 3
  • 7
2

For skipping callbacks in Rails 3, you can use update_all for your given purpose.

Source: update_all

The full list for skipping callbacks are here:

  • decrement
  • decrement_counter
  • delete
  • delete_all
  • find_by_sql
  • increment
  • increment_counter
  • toggle
  • touch
  • update_column
  • update_all
  • update_counters

Source: Skipping Callbacks

Jonathan Lin
  • 19,922
  • 7
  • 69
  • 65
2

If you are trying to update the record skipping all callbacks and validations you could use update_columns passing the attributes hash. This method will update the columns direct on database.

For example:

object.update_columns(name: 'William')

If you want to create a new object, unfortunately I think there is no method to skip both validations and callbacks. save(:validate => false) works for validations. For callbacks you could use skip_callback but be careful, your code probably will not be thread-safe.

William Weckl
  • 2,435
  • 4
  • 26
  • 43
2

Skipping callbacks is a bit tricky. Some plugins and adapters add their own "essential" callbacks (acts_as_nested_set, oracle_enhanced_adapter as examples).

You could use the skip_callback and set_callback methods in checking which ones you'd be able to skip.

Some custom class methods could help:

  def skip_all_callbacks(klass)
    [:validation, :save, :create, :commit].each do |name|
      klass.send("_#{name}_callbacks").each do |_callback|
        # HACK - the oracle_enhanced_adapter write LOBs through an after_save callback (:enhanced_write_lobs)
        if (_callback.filter != :enhanced_write_lobs)
          klass.skip_callback(name, _callback.kind, _callback.filter)
        end
      end
    end
  end



  def set_all_callbacks(klass)
    [:validation, :save, :create, :commit].each do |name|
      klass.send("_#{name}_callbacks").each do |_callback|
        # HACK - the oracle_enhanced_adapter write LOBs through an after_save callback (:enhanced_write_lobs)
        if (_callback.filter != :enhanced_write_lobs)
          klass.set_callback(name, _callback.kind, _callback.filter)
        end
      end
    end
  end
tamersalama
  • 4,093
  • 1
  • 32
  • 35
0

http://guides.rubyonrails.org/active_record_validations_callbacks.html details a small list of methods that avoid callbacks and validations - none of these include 'save' though.

However, the point of validations and callbacks is to enforce business logic. If you're avoiding them - you should ask yourself why.

See also: How can I avoid running ActiveRecord callbacks?

Community
  • 1
  • 1
Frankie Roberto
  • 1,349
  • 9
  • 9