Ruby on rails 事务回调前的ActiveRecord

Ruby on rails 事务回调前的ActiveRecord,ruby-on-rails,ruby,ruby-on-rails-3,activerecord,Ruby On Rails,Ruby,Ruby On Rails 3,Activerecord,问题:我正在寻找一个ActiveRecord(Rails 3.2)回调挂钩,它将在DB事务开始之前执行 如果它不存在(我认为它不存在),那么我将在monkey patching ActiveRecord中寻找任何建议,以便我们可以自己实现这种方法 我尝试过的 在查看了ActiveRecord文档和代码之后,似乎只有“在提交后”才能保证在事务之外执行。其他所有内容(“验证前”、“保存前”、“提交前”)都在事务中运行。我已尝试重写“transaction”方法: class User < Ac

问题:我正在寻找一个ActiveRecord(Rails 3.2)回调挂钩,它将在DB事务开始之前执行

如果它不存在(我认为它不存在),那么我将在monkey patching ActiveRecord中寻找任何建议,以便我们可以自己实现这种方法

我尝试过的

在查看了ActiveRecord文档和代码之后,似乎只有“在提交后”才能保证在事务之外执行。其他所有内容(“验证前”、“保存前”、“提交前”)都在事务中运行。我已尝试重写“transaction”方法:

class User < ActiveRecord::Base
  included do |base|
    base.instance_eval do
    def before_transaction
      ### DO STUFF
    end

    def transaction(options = {}, &block)
       before_transaction { super(options, &block) }
    end
  end
end
鉴于ActiveRecord的实现方式,我不确定我想要什么是可能的,因为可能无法知道另一个事务是否已经开始并调用回调。无论如何,我觉得在这里值得一问

背景

我正在尝试将现有的Rails模型(我们称之为User)与驻留在Elswere的用户服务“同步”。用户服务应该成为真相的来源

每当Rails用户模型发生更新时,我都想先验证并提交对用户服务的更改,然后再保存到DB(只有Rails项目使用)。然后,Rails项目的DB充当直写缓存(为什么要将数据库用作缓存?遗留代码原因)


如果我们可以在写入DB之前调用服务,我们就不必担心回滚事务(以及处理回滚失败时发生的事情!)。但是,我不愿意在开放的DB事务中间调用服务,这就是为什么我要查看是否可以建立一个“预事务”回调。< /P> < P>为什么不写一个处理所有这些功能的服务对象?< /P>
class UserService
  attr_accessor :user

  def initialize(user, params)
    @user = user
    @params = params
  end

  def save
    external_result = API.call_to_external

    if external_result
      @user.update(@params)
    end
  end
end

user_service = UserService.new(user, params)
user_service.save

为什么不编写一个处理所有这些功能的服务对象呢

class UserService
  attr_accessor :user

  def initialize(user, params)
    @user = user
    @params = params
  end

  def save
    external_result = API.call_to_external

    if external_result
      @user.update(@params)
    end
  end
end

user_service = UserService.new(user, params)
user_service.save

谢谢你的建议,这是个好主意。我唯一担心的是它的级别比模型本身高,我们可能会错过直接修改用户对象的地方——例如,Rails中模型之间的关系将继续工作,而不使用这个新的UserService对象。公平点。但是,如果您的外部服务是您的真实来源,那么我看不出您应该依赖rails关系(回调、嵌套属性等)的场景。似乎每个更新调用都应该首先命中此外部服务。你永远不应该直接调用.update?我同意,我只是认为跟踪所有直接调用.update的操作有点棘手,因为这些调用可能是隐式的(关系就是这样一个例子)。不过,我认为过度使用“保存”和“更新”以及其他抛出错误的方法可能是追踪错误的好方法。谢谢你的建议——这是个好主意。我唯一担心的是它的级别比模型本身高,我们可能会错过直接修改用户对象的地方——例如,Rails中模型之间的关系将继续工作,而不使用这个新的UserService对象。公平点。但是,如果您的外部服务是您的真实来源,那么我看不出您应该依赖rails关系(回调、嵌套属性等)的场景。似乎每个更新调用都应该首先命中此外部服务。你永远不应该直接调用.update?我同意,我只是认为跟踪所有直接调用.update的操作有点棘手,因为这些调用可能是隐式的(关系就是这样一个例子)。不过,我认为过度使用“保存”和“更新”以及其他抛出错误的方法可能是追踪错误的好方法。