覆盖rails 4 delete_all

时间:2016-01-18 22:28:23

标签: ruby-on-rails ruby-on-rails-4 activerecord

我已经写了一个问题,要包含在数据模型中,这些模型将管理我们表格中的可审计字段。这成功覆盖了deletedestroy& update,但我无法抓住执行不良delete_all

DELETE * FROM ....
module Concerns
  module Auditable
    extend ActiveSupport::Concern

    def auth_id
      Authentication.current ? Authentication.current.id : nil
    end

    def deletion_attributes
      { deleted_at: Time.now.utc, deleted_by: auth_id,
        modified_at: Time.now.utc, modified_by: auth_id }
    end

    def touch
      self.created_at ||= Time.now.utc
      self.created_by ||= auth_id
      self.modified_at = Time.now.utc
      self.modified_by = auth_id
    end

    def deleted?
      deleted_at.present?
    end

    def delete
      destroy
    end

    def destroy
      # destroy_associates (still to implement)
      update_attributes(deletion_attributes)
    end

    def undelete
      update_attributes(deleted_at: nil, deleted_by: nil,
                        modified_at: Time.now.utc, modified_by: auth_id)
    end

    def delete_all
      puts "this is never reached"
    end

    # Set ActiveRecord::Base of caller
    def self.included(base)
      unless base.ancestors.include?(ActiveRecord::Base)
        fail "You can only include this if #{base} extends ActiveRecord::Base"
      end
      base.class_eval do
        default_scope { where("#{table_name}.deleted_at IS NULL") }
        before_save :touch

        def self.show_deleted
          unscoped.where("#{table_name}.deleted_at IS NOT NULL")
        end

        def delete_all
          puts "this is also never reached"
        end
      end
    end
  end
end

2 个答案:

答案 0 :(得分:1)

destroy_all怎么样?当使用来自docsdelete_all时,不会调用回调#34;删除匹配条件的记录而不首先实例化记录,因此不调用destroy方法也不调用回调。这是一个直接进入数据库的单个SQL DELETE语句,比destroy_all更有效。"

答案 1 :(得分:0)

我认为这不是覆盖类方法的正确方法。

def self.included(base)
  unless base.ancestors.include?(ActiveRecord::Base)
    fail "You can only include this if #{base} extends ActiveRecord::Base"
  end
  base.class_eval do
    default_scope { where("#{table_name}.deleted_at IS NULL") }
    before_save :touch

    def self.show_deleted
      unscoped.where("#{table_name}.deleted_at IS NOT NULL")
    end

    def delete_all
      puts "this is also never reached"
    end
  end
end

这样对我有用

  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def delete_all
      # do nothing
    end
  end

并确保prepend Concerns::Auditable覆盖类方法。

class User < ActiveRecord::Base
  prepend Concerns::Auditable
end

您还可以使用gem ActsAsParanoid。它为你完成了工作!