Module: DeletedAt::Relation

Defined in:
lib/deleted_at/relation.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.prepended(subclass) ⇒ Object



5
6
7
8
9
# File 'lib/deleted_at/relation.rb', line 5

def self.prepended(subclass)
  subclass.class_eval do
    attr_writer :deleted_at_scope
  end
end

Instance Method Details

#build_arelObject



32
33
34
35
36
37
38
39
# File 'lib/deleted_at/relation.rb', line 32

def build_arel
  super.tap do |arel|
    if (subselect = deleted_at_subselect(arel)) && !arel.froms.include?(subselect)
      DeletedAt.logger.debug("DeletedAt sub-selecting from #{subselect.to_sql}")
      arel.from(subselect)
    end
  end
end

#delete_all(*args) ⇒ Object

Deletes the records matching conditions without instantiating the records first, and hence not calling the destroy method nor invoking callbacks. This is a single SQL DELETE statement that goes straight to the database, much more efficient than destroy_all. Be careful with relations though, in particular :dependent rules defined on associations are not honored. Returns the number of rows affected.

Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')")
Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else'])
Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all

Both calls delete the affected posts all at once with a single DELETE statement. If you need to destroy dependent associations or call your before_* or after_destroy callbacks, use the destroy_all method instead.

If an invalid method is supplied, delete_all raises an ActiveRecord error:

Post.limit(100).delete_all
# => ActiveRecord::ActiveRecordError: delete_all doesn't support limit


60
61
62
63
64
65
66
67
68
69
# File 'lib/deleted_at/relation.rb', line 60

def delete_all(*args)
  conditions = args.pop
  if conditions
    ActiveSupport::Deprecation.warn("      Passing conditions to delete_all is not supported in DeletedAt\n      To achieve the same use where(conditions).delete_all.\n    MESSAGE\n  end\n  update_all(klass.deleted_at_attributes)\nend\n".squish)

#deleted_at_scopeObject



11
12
13
# File 'lib/deleted_at/relation.rb', line 11

def deleted_at_scope
  @deleted_at_scope ||= :Present
end

#deleted_at_selectObject



15
16
17
18
19
20
21
22
# File 'lib/deleted_at/relation.rb', line 15

def deleted_at_select
  scoped_arel = case deleted_at_scope
  when :Deleted
    table.where(table[deleted_at[:column]].not_eq(nil))
  when :Present
    table.where(table[deleted_at[:column]].eq(nil))
  end
end

#deleted_at_subselect(arel) ⇒ Object



25
26
27
28
29
30
# File 'lib/deleted_at/relation.rb', line 25

def deleted_at_subselect(arel)
  if (subselect = deleted_at_select)
    subselect.project(arel_columns(columns.map(&:name)))
    Arel::Nodes::TableAlias.new(Arel::Nodes::Grouping.new(subselect.ast), table_name)
  end
end