13
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

destroy_allとdelete_all

Last updated at Posted at 2018-03-13

概要

ActiveRecord::Relationdestroy_alldelete_all のメソッドの違いを検証

destroy_all

  • records の要素1つ1つに対して destroyreset を実行
  • レコード数の多い条件に対して実行する際は要注意
    def destroy_all
      records.each(&:destroy).tap { reset }
    end

delete_all

  • 直接SQLを実行し、対象のレコード全てに対して DELETE を実行する
  • レコード数が多い場合は destroy_all よりも早く実行できるが、 destroy は呼ばれないので、 削除時のバリデーションや callback 等が呼ばれないことに要注意
  • INVALID_METHODS_FOR_DELETE_ALL ( = distinct group having )等の集計関数を含んでいる場合は raise される
    def delete_all
      invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select do |method|
        value = get_value(method)
        SINGLE_VALUE_METHODS.include?(method) ? value : value.any?
      end
      if invalid_methods.any?
        raise ActiveRecordError.new("delete_all doesn't support #{invalid_methods.join(', ')}")
      end

      if eager_loading?
        relation = apply_join_dependency
        return relation.delete_all
      end

      stmt = Arel::DeleteManager.new
      stmt.from(table)

      if has_join_values? || has_limit_or_offset?
        @klass.connection.join_to_delete(stmt, arel, arel_attribute(primary_key))
      else
        stmt.wheres = arel.constraints
      end

      affected = @klass.connection.delete(stmt, "#{@klass} Destroy")

      reset
      affected
    end

13
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?