Marcio Trindade

Assine o RSS

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?

console
>> 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

console
>> 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

console
>> 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?

console
>> 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

console
>> 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 findbyname no filtro before_save.

attribute_change

console
>> 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!

console
>> 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

blog comments powered by Disqus