Como obter o valor original de um atributo no Rails

96

existe uma maneira de obter o valor original de um atributo ActiveRecord (= o valor que foi carregado do banco de dados)?

Eu quero algo assim em um observador

before_save object
  do_something_with object.original_name
end

A tarefa é remover o objeto de uma tabela hash (na verdade, movê-lo para outra chave na tabela) durante a atualização.

Leonid Shevtsov
fonte

Respostas:

243

Antes dos trilhos 5.1

Anexar _wasao seu atributo fornecerá o valor anterior.

Para trilhos 5.1+

Copiado da resposta de Lucas Andrade abaixo : https://stackoverflow.com/a/50973808/9359123


Anexar _wasestá obsoleto no rails 5.1, agora você deve anexar_before_last_save

Algo como:

before_save object
  do_something_with object.name_before_last_save
end

Retornará o valor do nome antes de seu último salvamento no banco de dados (funciona para salvar e criar)


A diferença entre _wase de _before_last_saveacordo com a documentação:

_foi fonte do docs

def attribute_was(attr)
  attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
end

_before_last_save fonte de documentos

def attribute_before_last_save(attr_name)
  mutations_before_last_save.original_value(attr_name)
end
Vincent
fonte
7
Por exemplo: para self.context:self.context_was
Freedom_Ben
2
Onde está a documentação para isso?
j vai
4
a documentação pode ser encontrada em apidock.com/rails/ActiveModel/Dirty/attribute_was
hexinpeter
Na documentação, não há aviso de "descontinuação" para _was.
Rael Gugelmin Cunha
11

Para trilhos 5.1+

Anexar _wasestá obsoleto no rails 5.1, agora você deve anexar_before_last_save

Algo como:

before_save object
  do_something_with object.name_before_last_save
end

Retornará o valor do nome antes de seu último salvamento no banco de dados (funciona para salvar e criar)


A diferença entre _wase de _before_last_saveacordo com a documentação:

_foi fonte do docs

def attribute_was(attr)
  attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
end

_before_last_save fonte de documentos

def attribute_before_last_save(attr_name)
  mutations_before_last_save.original_value(attr_name)
end

Você pode ver um exemplo melhor aqui

Lucas andrade
fonte
1
attribute_wasfoi preterido em favor de attribute_in_database, enquanto attribute_before_last_saveé um método completamente novo a partir do 5.1 que não tem equivalente nas versões anteriores do Rails. Fonte: github.com/rails/rails/pull/25337#issuecomment-225166796
ohaleck