【问题标题】:Rails loses change tracking when calling instance method调用实例方法时 Rails 丢失更改跟踪
【发布时间】:2014-11-29 20:38:06
【问题描述】:

在控制器更新中更改模型的属性时,我想生成即将进行的更改的历史记录。为此,我创建了一个方法 generate_history 从实例访问。

班级:

class Assist < ActiveRecord::Base
    belongs_to: status

    def generate_history
        #Also tried without self

        p 'Testing round two'
        p 'Status' + self.status.id.to_s
        p 'Modified: ' + self.status.id_changed?.to_s
        p 'Old value ' + self.status.id_was.to_s

        #do something something dark side
    end

end

问题在于该方法,ActiveModel::Dirty 不知道所做的更改,尽管self.status_id 的值是新值。

同时在控制器中:

def update

    ...

    @assist.assign_attributes(assist_params)

    p 'Testing round one'
    p 'Status' + @assist.status_id.to_s
    p 'Modified: ' + @assist.status_id_changed?.to_s
    p 'Old value ' + @assist.status_id_was.to_s

    p 'Generating history'

    @assist.generate_history

    p 'Testing round three'
    p 'Status' + @assist.status_id.to_s
    p 'Modified: ' + @assist.status_id_changed?.to_s
    p 'Old value ' + @assist.status_id_was.to_s
end

起初我怀疑assign_attributes 会以某种方式干扰ActiveModel::Dirty,但我意识到ActiveModel::Dirty 在控制器中工作,其中值正在被修改,但不是在我调用generate_history 时.

我是在实例方法中做错了什么,还是 ActiveModel::Dirty 的工作方式有问题?

输出示例:

Testing round one
Status 1
Modified: true
Old value 2

Generating history
Testing round two
Status 1
Modified: false
Old value 1

Testing round three
Status 1
Modified: true
Old value 2

【问题讨论】:

  • 您是否尝试过通过status 属性查找“脏”?而不是.status_id,请尝试.status.id.status_changed?。它可能会起作用......
  • @mr-rogers .status.changed? 在方法内报告错误
  • 伤心。不错,值得一试。
  • @mr-rogers 实际上,你是对的。我在 generate_history 方法中有 .status.id 和 .status.id.changed? (报告没有修改)当我测试 .status_id.changed 的​​输出时?在控制器中。你能把它作为答案吗?
  • 当然。很高兴这有帮助。让我知道发布的答案是否与您的工作相符。我吐了……

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


【解决方案1】:

我的猜测是status_id 不是ActiveRecord::Dirty 完全跟踪的属性。而不是看status_id,我认为你应该看status。比如:

class Assist < ActiveRecord::Base
    belongs_to: status
    def generate_history
        p 'Testing round two'
        p 'Status' + status_id.to_s
        p 'Modified: ' + status_id_changed?.to_s
        p 'Old value ' + status_id_was.to_s

        #do something something dark side
    end
end

那么你的控制器代码是对的。

因为您没有分配 status 而只是询问它,所以您可能不需要 self.

【讨论】:

  • 其实恰恰相反。 status_id 是正在更新的实际字段,因为它来自参数
  • 知道了。我刚刚在我的一个项目上尝试过,并看到了不同之处。点和下划线是很滑的吸盘。
猜你喜欢
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 2013-08-29
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多