Rails,Globalize3 检查翻译后的属性是否改变?

Rails, Globalize3 check if translated attributes changed?

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

检查模型属性是否已更改

假设我有一个使用 Globalize3 的模型。

translates :name

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

类似 obj.name_changed?

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

查看翻译后的属性是否发生变化,只需要在相应的模型class.

中打开Globalize3提供的Translation class
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

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

假设你有

class Post < ActiveRecord::Base
  translates :name
end

如果你实例化一个post:

p = Post.last

检查其名称:

p.name
=> "My old name"

并更改名称:

p.name = "My new name"

如果你这样做:

p.name_changed?

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

如果按照您的建议,从模型中调用翻译 class:

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

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

除了从方法中调用 class,您还可以尝试(在保存 post 之前)a:

p.translation.name_changed?
=> false

结果将为假。这是可以解释的。如果,在使用以下名称更改名称后:

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

p.translation.name 将 return:

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"

还有这个,在保存 post.

之前