在rails中使用_was方法

时间:2016-02-05 19:36:38

标签: ruby-on-rails ruby

所以我试图在属性上使用_was方法。 假设我有一个对象Person

Person.name = "new name"

Person.name_was = "old name"

如果我打电话给Person.changed?,它会返回["name"]

所以我的问题是:我能以某种方式使用person.changed中的值来做这样的事情:

Person.changed.each do |x|
  Person.x => returns undefined value for x
  Person['x'] => returns new name
  Person["#{'x'}_was"] => errors
end

有没有办法可以将_was方法与x中的字符串变量一起使用?

3 个答案:

答案 0 :(得分:0)

如果您在变量中有属性的名称,则可以使用send。此外,Person可能是一个类,我想你更愿意使用一个实例。试试:

person = Person.first

# stuff happens...

person.changed.each do |x|
  person.public_send(x)
  person.public_send("#{x}_was")
end

或者不要重新发明方向盘,只需使用person.changes即可。看看ActiveModel::Dirty module

答案 1 :(得分:0)

您可以使用' public_send'或者'方法'方法

person = Person.first

person.name # => 'Jhon Doe'
person.gender # => 'M'
person.birthdate # => Wed, 05 Sep 1984

person.name = 'Jane Doe'
person.gender = 'F'

person.changed.each do |attr|
  p person.public_send(attr) # => person.name => 'Jane Doe'
  p person.method(attr).call      # => person.name => 'Jane Doe'
  p person.public_send("#{attr}_was") # => person.name_was => 'Jhon Doe'
  p person.method("#{attr}_was").call      # => person.name_was => 'Jhon Doe'
end

_was属性是getter,没有setter。

答案 2 :(得分:0)

我不太确定示例代码试图实现的是什么,但我认为您正在寻找#changes方法;

person = Person.create(first_name: 'John', last_name: 'Doe', sex: 'Male')
person.first_name = 'Jane'
person.sex = 'Female'
person.changes.each do |attribute, change|
  puts attribute
  puts change.first
  puts change.last
end

# => 'first_name'
# => 'John'
# => 'Jane'
# => 'sex'
# => 'Male'
# => 'Female'

person.changes返回一个包含所有更改的哈希值; {attribute_name => [之前,之后]}