【问题标题】:Rails: how to overwrite :destroy method?Rails:如何覆盖 :destroy 方法?
【发布时间】:2012-02-17 18:03:05
【问题描述】:

我尝试了很多方法来覆盖 :destroy 方法的行为,但没有任何效果。我首先使用了acts_as_paranoia 插件,但它不适用于has_many :through 关联中的模型。

我想覆盖 :destroy 方法只是为了做这样的事情:

  def destroy
    _run_destroy_callbacks { delete }
  end

  def delete    
    self.update_attribute(:status => 0)
    freeze
  end

也就是说,我只想更新另一个字段(状态为 0),而不是销毁记录本身。

【问题讨论】:

    标签: ruby-on-rails destroy


    【解决方案1】:

    你试过了吗?:

     class MyClass < ActiveRecord::Base
      def destroy
        update_attribute(:status, 0)
      end
     end
    

    编辑:基于 cmets,可能还有其他东西在起作用,它可能只是关联定义上的 (:dependent=>'') 名称——或者如果它是一个 HABTM,它可能根本不起作用。也许this info on delete and destroy through associations 会有所帮助?在下面粘贴相关部分:

    删除还是销毁?

    has_many 和 has_and_belongs_to_many 关联有方法 销毁、删除、destroy_all 和 delete_all。

    对于 has_and_belongs_to_many,delete 和 destroy 是一样的:它们 导致连接表中的记录被删除。

    对于 has_many,destroy 总是会调用 删除记录以便运行回调。但是删除会 要么根据指定的策略进行删除 :dependent 选项,或者如果没有给出 :dependent 选项,那么它将 遵循默认策略。默认策略是:nullify(设置 外键为零),除了 has_many :through,默认 策略是 delete_all (删除连接记录,而不运行它们 回调)。

    【讨论】:

    • 是的,这是我尝试的第一件事。这无济于事。我可以在我的日志中看到 DELETE FROM 请求。自定义的destroy方法好像没有被调用。
    • Hrm,我实际上在几个应用程序的几个模型中使用了它,它可以正常工作。这个特定模型有什么“特殊”吗?您是在调用删除还是销毁?你会想要后者。
    • 记录在 AREL(ActiveRecord 关系)中从其父级销毁,也许是问题所在?事实上,我更新了我的葡萄酒模型和记录(主窗体,控制器中的更新方法),如果我选择删除子项(包含自定义销毁的品种模型),它显然不会被调用。也许,如果它是破坏孩子的父母(不要在孩子模型上调用破坏?)
    • 实际上很难说,我从 AR 文档中添加了一个 sn-p,也许这会发现一些东西。
    • 感谢您的帮助和建议。葡萄酒模型和品种模型之间的关系是“has_many through”。我读了你的纺纱网,我试过“破坏,删除,删除全部”......但它是一样的。我希望你明白我的问题是当我更新主模型(葡萄酒)时,而不是我想销毁它(并销毁孩子)。例如,我创建了一种葡萄酒(并添加了一个品种)然后我想更新葡萄酒(并选择销毁添加的品种)=> 这是我的问题,我显示了 DELETE FROM varietals(而不是 UPDATE 到 status=0 ) 和 UPDATE WINE (OK)...
    【解决方案2】:

    正如 Miked 所说,如果我们想“手动”销毁品种,这段代码非常有用:

    @varietal = Varietal.find('1')    
    @varietal.destroy 
    
    def destroy
      update_attribute(:status, 0)
    end
    

    这非常有效。但是,正如我所说,如果我们更新父记录,我没有找到对子调用的destroy/delete/delete_all方法......所以如果有人有想法......

    【讨论】:

      【解决方案3】:

      我认为最好的方法是覆盖 before_destroy: 过滤器来操作依赖项:

      def Model
          before_destroy: mark_as_deleted
      
          def mark_as_deleted  
              self.update_attribute(:status => 0)
          end
      end
      

      虽然这不会取消destroy

      The full callback documentation is here.

      【讨论】:

      • 这仍然在控制器中调用destroy(),它只是先运行你的def。返回 false 不起作用,至少我不能说。
      • 这个答案不正确。如果您拨打before_destroy,即使更新后记录也会被删除。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      • 2012-10-14
      • 2011-02-22
      相关资源
      最近更新 更多