【问题标题】:Getting changes made to record from within the controller从控制器中获取要记录的更改
【发布时间】:2015-11-10 11:51:26
【问题描述】:

这是我认为非常容易的事情,但事实证明并非如此。

我试图在我的 FooBarsController 的更新操作中找到对某些记录所做的更改(我们称之为 FooBar)。

不幸的是,ActiveRecord::Persistence 中定义的 .update 方法似乎不会更新记录上的 changes 属性。

例如:

def update
  @resource = FooBar.find(params[:id])
  if @resource.update(resource_params)
    @resource.changes # => {} 
    render json: @resource
  else
    render_validation_errors @resource.errors
  end
end

这是为什么?有人知道如何进行更改吗?

注意:我不想使用模型挂钩。我尝试在更改中使用的代码将使用current_user 方法,因此,使用模型挂钩会很脏。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 model-view-controller controller


    【解决方案1】:

    找到了!

    所以有一个奇妙的东西叫做.previous_changes,它可以找到之前事务中所做的更改,因此依赖于要调用的更新方法,而不是避免它。

    有了这个,我可以做到:

    def update
      @resource = FooBar.find(params[:id])
      if @resource.update(resource_params)
        @resource.previous_changes # => {'some' => 'changes', 'attribute' => 'new value'} 
        render json: @resource
      else
        render_validation_errors @resource.errors
      end
    end
    

    【讨论】:

    • 不能再接受两天的回答,所以如果有人在那之前看到这个帖子或者我忘记标记它(更有可能),我会继续记录说这很好用.
    【解决方案2】:

    我认为您正在寻找ActiveModel::Dirty 模块。

    它有一个changed_attributes 方法,该方法将为您提供属性的哈希值,其中未保存的更改指示其原始值

    例如

    person.name # => "bob"
    person.name = 'robert'
    person.changed_attributes # => {"name" => "bob"}
    

    此外,还有一个不错的 gem paper_trail,它可以帮助跟踪模型数据的变化。这对你也可能有用!从它的 github 页面:

    跟踪模型的更改,以进行审核或版本控制。看看如何 模型查看其生命周期中的任何阶段,将其还原为任何版本, 或在它被破坏后恢复它。

    【讨论】:

    • 我相信update 方法将保存调用包装在事务中。我不想删除它,因为担心它会破坏未来的 Rails 迭代,或者更糟。有人可能也有可能正在做猴子补丁的 gem,或者只是依赖于 update 方法将被调用的事实。如果是这样的话,这个解决方案对他们不起作用。这些似乎是有效的担忧吗?编辑:确实如此,请查看github.com/rails/rails/blob/…
    • 不幸的是,这仍然行不通,(假设是这样)由于事务包装了update。当我尝试它时,我得到了与使用 .changes 方法收到的相同的空哈希。
    • paper_trail 太棒了!我完全同意,但这对我的目的来说有点过头了。
    猜你喜欢
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多