Как вернуть/отменить локальные изменения объекта Activerecord?

Есть ли способ отменить/отменить любые локальные изменения объекта Activerecord. Например:

user = User.first
user.name # "Fred"
user.name = "Sam"
user.name_was # "Fred"

user.revert
user.name # "Fred"

Я знаю, что могу сделать user.reload, но мне не нужно было ударять по базе данных, чтобы сделать это, поскольку старые значения хранятся в состоянии объекта.

Предпочтительно решение Rails 3.

Ответ 1

Вы можете просто пропустить "изменения" и reset их. Может быть метод, который делает это, но я не смотрел.

> c = Course.first
> c.name
=> "Athabasca Country Club"
> c.name = "Foo Bar"
=> "Foo Bar"
> c.changes
=> {"name"=>["Athabasca Country Club", "Foo Bar"]}
> c.changes.each {|k,vs| c[k] = vs.first}
> c.name
=> "Athabasca Country Club"

На самом деле выглядит так: "name_reset!" метод, который вы могли бы назвать...

> c.changes.each {|k,vs| c.send("#{k}_reset!")}

Ответ 3

Как упоминалось в этом ответе Rails 4.2 представил метод restore_attributes в ActiveModel::Dirty:

user = User.first
user.name   # "Fred"
user.status # "Active"

user.name = "Sam"
user.status = "Inactive"
user.restore_attributes
user.name   # "Fred"
user.status # "Active"

Если вы хотите восстановить определенный атрибут, можно использовать restore_attribute!:

user.name = "Sam"
user.status = "Inactive"
user.restore_name!
user.name   # "Fred"
user.status # "Inactive"

Ответ 4

Это еще один метод для атрибутов reset из базы данных:

user.reload