Rails - 更改关联不会将对象标记为脏

时间:2012-07-12 21:05:01

标签: ruby-on-rails activerecord

修改:已添加说明

给出以下两个类

class Foo < ActiveRecord::Base
  belongs_to :bar
end

class Bar < ActiveRecord::Base
end

当我更改foo上的一个栏时,我想要一种方法来查看foo实例已经改变:

foo = Foo.find(x)
foo.bar      # returns #<Bar id:1>
foo.bar = Bar.new
foo.changed? # returns false
foo.changes  # returns an empty hash

我不想将bar_id设置为脏(因为它没有改变)。拥有以下内容会很好:

foo.changed? # returns true
foo.changes  # returns {:bar => [#<Bar id: 1>, nil]}

有没有一种聪明的方法可以将其破解为Rails?有没有理由这不是Rails的一部分?

3 个答案:

答案 0 :(得分:3)

今天我遇到了同样的问题,在通过rails-source运行后,如果我以正确的方式得到你的问题,我找到了一个应该按照你的想法做的解决方法。

转移到您的示例代码应如下所示:

class Foo < ActiveRecord::Base
  belongs_to :bar

  def info
    bar.info
  end

  def info=(val)
    @changed_attributes[:info] = self.info unless val == self.info
    self.time_entry.update_attributes! :info => val
  end
end

class Bar < ActiveRecord::Base
  attr_accessible :info
end

这样你可以打电话给.changed吗?和。改变Foo类的对象。

希望这有助于即使答案有点迟了:)

亲切的问候 基督教

顺便说一句。抱歉英语不好。我正在努力研究我的红宝石技能;)

答案 1 :(得分:2)

您使用的是什么版本的Rails?当我测试它时,它确实报告了。

无论如何,我不确定是否可以为belongs_to使用after assign回调。这是一张票 https://github.com/rails/rails/issues/586

如果没有,您可以覆盖assign方法 (我之前没试过,但我认为它会起作用:)所以请让我知道)

class Foo < ActiveRecord::Base
  belongs_to :bar

  def bar=(b)
    bar_id_will_change! unless bar_id == b.id
    super        
  end

end

更新:再次阅读你的问题,我甚至不确定我是否理解了所有这些问题。如果它没有改变,你希望它仍然报告真实吗?即使再次分配同一个对象呢?在这种情况下,您可以删除unless bar_id == b.id部分

答案 2 :(得分:0)

由于在Rails 5.1中对@changed_attributes的更改,我不得不求助于使用虚拟属性(attr_accessor)在检查后指示更改的关联。与弄乱与ActiveRecord::Dirty

相关的Rails内部相比,从长远来看,这可能更好
相关问题