Edge Rails: Partial Updates

14 de abril de 2008  |  Rails 2.1  | 

Na última sexta-feira eu falei sobre Dirty Objects, e disse que aquela novidade seria o gancho para uma outra ainda mais interessante.

Já que agora podemos rastrear quais atributos foram alterados na instancia do objeto, porque não usar isto para evitar atualizações desnecessários no banco de dados?

Hoje quando executamos o método save em um ActiveRecord já existente, será executado no banco de dados um UPDATE em todas as colunas da tabela, mesmo para as que não sofreram alterações.

Com o Dirty Objects isto poderia ser melhorado, e foi exatamente o que aconteceu. Veja o SQL gerado ao tentar salvar um registro que sofreu apenas uma leve alteração no Rails 2.1:

article = Article.find(:first)
article.title  #=> "Title"
article.subject  #=> "Edge Rails"

# Vamos atualizar um atributo...
article.title = "New Title"

# Veja o SQL criado ao persistir o objeto
article.save
#=>  "UPDATE articles SET title = 'New Title' WHERE id = 1"

Note que apenas o atributo alterado será atualizado no banco de dados. Se nenhum atributo fosse alterado, o ActiveRecord não executaria nenhum update.

Para habilitar/desabilitar esta nova funcionalidade você deve alterar a propriedade partial_updates dos seus models.

# Para habilitar a funcionalidade...
MinhaClasse.partial_updates = true

Se deseja habilitar/desabilitar esta funcionalidade para todos os models do seu sistema acrescente esta linha no arquivo environment.rb ou em algum arquivo no diretório config/initializer:

# Habilitando para todos os meus models
ActiveRecord::Base.partial_updates = true

Atualmente o arquivo config/initializers/new_rails_defaults.rb já tem esta linha, mas ele deve ser removido mais para frente.

Atenção: Não se esqueça de informar o ActiveRecord quando for alterar um atributo sem usar o método attr=, assim:

# Se eu fizer assim, tudo bem...
person.name = 'bobby'
person.name_change    # => ['bob', 'bobby']


# Mas se eu não alterar o atributo usando o sinal de '='
# então preciso avisar que vou fazer uma alteração
person.name_will_change!
person.name << 'by'
person.name_change    # => ['bob', 'bobby']

Se não fizer isto este tipo de alteração não será rastreado, e sua tabela não será atualizada corretamente.



6 Comentários


  1. Olá Carlos, hoje instalei o ruby e rails (2.0.2) no ubuntu. Sempre que eu rodo algum scritp/generate model, ou rake db:migration, simplesmente não funciona, diz que o método partial_updates não existe.

    Comentei todo o código do new_rails_defaults.rb e agora ele está funcionando. Pelo visto, ainda não estarei usando o partial updates, é isso? Se for isso, como faço pra ele funcionar? (No meu caso, ele diz que o método não existe!!).

    Abraços

  2. Cairo, toda a série Edge Rails deste blog fala sobre o futuro do Rails. Nada que esta escrito nesta série vai funcionar no rails atual.

    Para conseguir usar isto vc precisa instalar o Edge Rails que é a versão de desenvolvimento dele. Hoje eu uso ela em um projeto e não tenho nenhum problema. Isto é bom se você pretende usar o Rails 2.1 quando sair.

    Eu já ensinei como instalar o Edge Rails neste screencast, dá uma assitida: http://www.nomedojogo.com/2008/01/02/screencast-3-edge-rails/

  3. Blz, agora o interessante, é que já veio nessa versão do Rails que instalei essa opção de update parcials.

  4. Encontrei um problema com as partial updates. Quando um valor integer é alterado, por exemplo, de 0 para ” (ex: ao deixar um campo em branco no form), ele não é persistido no banco. Alguém tem passado por isso?

    Ex:

    Model Pessoa
    – Nome: string
    – Idade: integer

    p = Pessoa.first
    p.update_attributes :nome => 'Joao', :idade => 30

    #Até aqui, os dois campos são atualizados

    p.update_attributes :nome => 'Marcos', :idade => 0

    #Aqui também, a idade foi alterada de 30 para 0.

    p.update_attributes :nome => 'Mateus', :idade => ''

    #Neste ponto, só o nome é alterado. A idade continua valendo 0. Alguém mais tem passado por isto?

    Um abraço!

    Felipe ;-)

  5. Estranho… preciso testar isto.

Trackbacks

  1. Dirty models and partial SQL updates for Rails 2.0.2 at Urubatan’s Weblog
  2. Nome do Jogo » Artigo » Edge Rails: Fechando as atualizações para o Rails 2.1
  3. Nome do Jogo » Artigo » Edge Rails: Novo helper para testes (assert_sql)

Deixe um comentário