【问题标题】:What is purpose of around_create callback in Rails Model?Rails 模型中 around_create 回调的目的是什么?
【发布时间】:2011-07-24 20:02:24
【问题描述】:

around_create回调代码什么时候执行,在什么情况下我们应该使用它?

【问题讨论】:

    标签: ruby ruby-on-rails-3 model callback


    【解决方案1】:

    我找到的关于回调的更简单明了的解释,如下所示

    around_* 回调在动作周围以及 before_* 和 after_* 动作内部被调用。例如:

    class User
      def before_save
        puts 'before save'
      end
    
      def after_save
        puts 'after_save'
      end
    
      def around_save
        puts 'in around save'
        yield # User saved
        puts 'out around save'
      end
    end
    
    User.save
      before save
      in around save
      out around save
      after_save
    => true
    

    原帖here

    【讨论】:

      【解决方案2】:

      除了Tom Harrison Jr's answer 关于日志记录和监控之外,我发现关键区别在于获得对操作是否运行的控制。否则,您可以实现自己的 before_*after_* 回调来做同样的事情。

      around_update 为例。假设您有一个不希望更新运行的情况。例如,我正在构建一个 gem,它将草稿保存在另一个 drafts 表中,但不将某些更新保存到“主”表中。

      around_update :save_update_for_draft
      
      private
      
      def save_update_for_draft
        yield if update_base_record?
      end
      

      这里引用的update_base_record? 方法的细节并不重要。您可以看到,如果该方法的计算结果不是 true,则更新操作根本不会运行。

      【讨论】:

        【解决方案3】:

        刚刚为我找到了一个用例:

        想象一下多态观察者的情况,观察者在某些情况下需要在保存之前执行操作,而在其他情况下需要在保存之后执行操作。

        使用环绕过滤器,您可以在一个块中捕获保存操作并在需要时运行它。

        class SomeClass < ActiveRecord::Base
        
        end
        
        class SomeClassObserver < ActiveRecord::Observer
          def around_create(instance, &block)
            Watcher.perform_action(instance, &block)
          end
        end
        
        # polymorphic watcher
        class Watcher
          def perform_action(some_class, &block)
            if condition?
              Watcher::First.perform_action(some_class, &block)
            else
              Watcher::Second.perform_action(some_class, &block)
            end
          end
        end
        
        class Watcher::First
          def perform_action(some_class, &block)
            # update attributes
            some_class.field = "new value"
        
            # save
            block.call
          end
        end
        
        class Watcher::Second
          def perform_action(some_class, &block)
            # save
            block.call
        
            # Do some stuff with id
            Mailer.delay.email( some_class.id )
          end
        end
        

        【讨论】:

          【解决方案4】:

          “环绕”过滤器的一个经典用例是衡量性能、记录或进行其他状态监控或修改。

          【讨论】:

            【解决方案5】:

            也有这个问题,现在找到了答案:around_create 基本上允许您在一种方法中同时执行before_createafter_create。您必须使用yield 来执行两者之间的保存。

            class MyModel < ActiveRecord::Base
              around_create :my_callback_method
            
              private
                def my_call_back_method
                  # do some "before_create" stuff here
            
                  yield  # this makes the save happen
            
                  # do some "after_create" stuff here
                end
            end
            

            【讨论】:

              【解决方案6】:

              around_create 在保存带有new? 标志的模型时调用。它可用于添加数据以添加/更改模型的值,调用其他方法等......我无法为这个回调提供特定的用例,但它完成了一组“之前,之后,周围”创建操作的回调。为查找、更新、保存和删除事件设置了类似的“之前、之后、周围”回调集。

              【讨论】:

                猜你喜欢
                • 2013-02-04
                • 1970-01-01
                • 1970-01-01
                • 2012-02-11
                • 2021-08-29
                • 1970-01-01
                • 2011-10-02
                • 1970-01-01
                • 2015-06-22
                相关资源
                最近更新 更多