Marcio Trindade

28Jul/091

Monitorando atributos com Rails

A partir do rails 2.1 ganhamos alguns métodos para monitorar as alterações dos atributos.
Com isso você passa a ter um grande ganho de performance para efetuar updates em seus projetos, por que o Rails passa a fazer update somente dos atributos que foram modificados. Vamos ver como isso acontece.

Para os exemplos abaixo vamos supor que eu tenha um model User com os atributos name e email

changed?

>> user = User.first 
=> #<User id: 1, name: "Daniel Burns", email: "meuemail@gmail.com">
>> user.changed?
=> false
>> user.name="Marcio Trindade"
=> "Marcio Trindade"
>> user.changed?
=> true
>> user.save
=> true
>> user.changed?
=> false

Como podemos observar no exemplo acima o método changed? retorna verdadeiro se o objeto tem o valor diferente do que está salvo no banco ou falso se o valor for o mesmo.

changed

>> user = User.first 
=> #<User id: 1, name: "Daniel Burns", email: "meuemail@gmail.com">
>> user.changed
=> []
>> user.name="Marcio Trindade"
=> "Marcio Trindade"
>> user.changed
=> ["namde"]
>> user.email="marciotrindade@gmail.com"
=> "marciotrindade@gmail.com"
>> user.changed
=> ["namde", "email"]
>> user.save
=> true
>> user.changed?
=> []

Parecido com o método acima este nos retorna um array com os atributos que foram atualizados.

changes

>> user = User.first 
=> #<User id: 1, name: "Daniel Burns", email: "meuemail@gmail.com">
>> user.changes
=> {}
>> user.name="Marcio Trindade"
=> "Marcio Trindade"
>> user.changes
=> {"name"=>["Daniel Burns", "Marcio Trindade"]}
>> user.email="marciotrindade@gmail.com"
=> "marciotrindade@gmail.com"
>> user.changes
=> {"name"=>["Daniel Burns", "Marcio Trindade"], "email"=>["meuemail@gmail.com", "marciotrindade@gmail.com"]}
>> user.save
=> true
>> user.changed?
=> {}

Este método retorna um hash sendo a chave o nome do atributo modificado e o valor um array com os atributo de antes e depois da alteração.

attribute_changed?

>> user = User.first 
=> #<User id: 1, name: "Daniel Burns", email: "meuemail@gmail.com">
>> user.name_changed?
=> false
>> user.name="Marcio Trindade"
=> "Marcio Trindade"
>> user.name_changed?
=> true

Parecido com o método changed? porém para um atributo específico.

attribute_was

>> user = User.first 
=> #<User id: 1, name: "Daniel Burns", email: "meuemail@gmail.com">
>> user.name_was
=> "Daniel Burns"
>> user.name="Marcio Trindade"
=> "Marcio Trindade"
>> user.name_was
=> "Daniel Burns"

Retorna o valor original do atributo (como está no banco de dados). Muito útil para recuperar um objeto pelo atributo, como por exemplo um find_by_name no filtro before_save.

attribute_change

>> user = User.first 
=> #<User id: 1, name: "Daniel Burns", email: "meuemail@gmail.com">
>> user.name_change
=> nil
>> user.name="Marcio Trindade"
=> "Marcio Trindade"
>> user.name_change
=> ["Daniel Burns", "Marcio Trindade"]

Retorna um array com os valores de antes e depois da alteração para um atributo específico.

attribute_will_change!

>> user = User.first 
=> #<User id: 1, name: "Daniel Burns", email: "meuemail@gmail.com">
>> user.name_will_changed!
=> nil
>> user.changes
=> {"name"=>["Daniel Burns", "Daniel Burns"]}

Seta o atributo como alterado e força o seu update no banco de dados.

Estas alteração no Rails já me foram úteis economizando linhas de código para verificar se um atributo havia sido modificado e então fazendo uma nova consulta no banco pra trazer o valor antes da modificação. Valeu Rails por mais esta facilidade.

Você pode ver um video em inglês explicando estes métodos aqui no screencast do Rain Bates

Comentário (1)

Deixe um comentário


(não será divulgado)