4

在 Rails 中,我们可以使用obj.field_changed?.

假设我有一个使用Globalize3.

它有translates :name

如何检查名称属性是否已更改?

就像是obj.name_changed?

4

2 回答 2

5

我不确定建议的答案是否真的会给您带来预期的结果。

说你有

class Post < ActiveRecord::Base
  translates :name
end

如果你实例化一个帖子:

p = Post.last

检查它的名字:

p.name
=> "My old name"

并更改名称:

p.name = "My new name"

如果你这样做:

p.name_changed?

你会得到一个无方法错误。

如果按照您的建议,您从模型中调用 Translation 类:

class Post < ActiveRecord::Base
  translates :name
  .......
  # Open the Translation class
  class Translation
    after_save do #you may define a private method as callback method
      if name_changed?
      #accomplish your tasks...
      end
    end
  end
end

只有在保存了主要可翻译记录后,您才能知道您的属性是否发生了变化。这可能不是您想要的(例如,假设您想要生成一个新的 slug,基于每次更改的帖子的新名称,然后您必须再次保存您的帖子)。

除了在方法中调用类,您还可以尝试(在保存帖子之前)a:

p.translation.name_changed?
=> false

结果将是错误的。这可以解释。如果,在更改名称后:

p.name = "My new name"
=> "My new name"

p.translation.name 将返回:

p.translation.name
=> "My old name"

这是因为 Globalize 将翻译后的属性存储在实例化可翻译模型的虚拟属性中。

你可以这样做:

p.translation.name = "My new name"
=> "My new name"

然后:

p.translation.name_changed?
=> true

但是,您会失去使用 Globalize 的部分好处。

我所做的是,在 Post 模型中,我覆盖了我感兴趣的虚拟属性的 getter 和 setter:

def name
  translation.name
end

def name=(val)
  translation.name = val
end

现在,如果我这样做:

p.name
=> "My old name"
p.name = "My new name"
=> "My new name"
p.name_changed?
# no method error
p.translation.name_changed?
=> true
p.translation.name
=> "My new name"

还有这个,在保存帖子之前。

于 2016-02-24T19:07:44.557 回答
3

我得到了解决方案。考虑到有人可能会受益,我将其发布为答案。

要检查翻译后的属性是否改变,只需要打开相应模型类内部Translation class提供的即可。Globalize3

class Post < ActiveRecord::Base
  translates :name
  .......
# Open the Translation class
  class Translation
    after_save do #you may define a private method as callback method
      if name_changed?
        #accomplish your tasks...
      end
    end
  end
end
于 2015-10-15T07:13:22.640 回答