Amit
Amit

Reputation: 3990

Override delete_all in rails

I want to add a :limit clause to delete_all... how can I do that?

One method I can think of is to override the default delete_all, but I cant get it to work... the add_conditions! function isn't defined!

Upvotes: 2

Views: 1779

Answers (2)

reto
reto

Reputation: 16732

This worked with mysql and rails 2.3

# in config/initializers/active_record_extensions.rb
class ActiveRecord::Base
  # like delete_all, but honors limit (either through scope ar as a option)
  def self.delete_all_limit(conditions = nil, limit=nil, offset=nil)
    scope = scope(:find)
    sql = "DELETE FROM #{quoted_table_name} "
    add_conditions!(sql, conditions, scope)
    add_limit!(sql, {:limit => limit, :offset => offset}, scope)
    connection.delete(sql, "#{name} Delete all limited")
  end
end

and an even uglier hack for oracle_enhanced adpater. (I assume this is better with rails3)

# in config/initializers/active_record_extensions.rb

module ActiveRecord
  class Base
    # like delete_all, but honors limit and offset (either through scope ar as a option)
    def self.delete_all_limit(conditions = nil, limit=nil, offset=nil)
      scope = scope(:find)
      q = self
      limit ||= scope[:limit] if scope

      if limit
        limit = limit.to_i
         q = q.scoped(:conditions => "rownum <= #{limit}")
      end

      return q.delete_all(conditions)
    end
  end
end

Upvotes: 1

idlefingers
idlefingers

Reputation: 32037

There's no need to override anything:

# Rails 2
SomeModel.scoped(:limit => 10).destroy_all

# Rails 3
SomeModel.limit(10).destroy_all

Edit: Passing spec:

it "should destroy all using scope" do
  10.times { SomeModel.create }
  expect {
    SomeModel.limit(5).destroy_all
  }.to change(SomeModel, :count).by(-5)
  SomeModel.count.should == 5
end

Upvotes: 4

Related Questions