Você está desenvolvendo um site institucional e cria um model Article. Daí sempre que você precisa obter a lista de Articles, o que acontece com muita frequência, faz a seguinte consulta:

Articles.where(published: true)

Mas o que você queria mesmo era chamar Articles.all e receber somente os artigos (Articles) publicados.

Default Scope

Alguém te dá a excelente idéia de usar default scope e você não hesita em sair implementando no seu código:

class Article < ActiveRecord::Base
  default_scope { where(published: true) }
end

Sucesso! Agora Article.all retorna somente os artigos publicados! Mas espera aí! E os não publicados?

Uma consulta rápida no Google te dá a resposta esperada:

Articles.unscoped.all

Duplo sucesso! Todos seus problemas estão resolvidos!

O perigo mora ao lado

Alguém, um estraga prazer, te avisa que todos os artigos estão sendo automaticamente criados como publicados (published: true) e você não consegue entender porque.

Uma ida rápida ao nosso amigo IRB revela o seguinte:

2.3.0 :001 > article = Article.create(title: "Teste", body: "Qualquer")
    (0.1ms)  begin transaction
SQL (1.1ms)  INSERT INTO "articles" ("published", "title", "body", "created_at",
"updated_at") VALUES (?, ?, ?, ?, ?)  [["published", "t"], ["title", "Teste"], 
["body", "Qualquer"], ["created_at", "2016-05-20 20:00:14.377031"],
["updated_at", "2016-05-20 20:00:14.377031"]]
   (0.9ms)  commit transaction
 => <Article id: 1, title: "Teste", body: "Qualquer", PUBLISHED: TRUE,
created_at: "2016-05-20 20:00:14", updated_at: "2016-05-20 20:00:14">

2.3.0 :002 > article.published
true

Como assim? Quando você criou um artigo, sem definir se publicado ou não, ele foi automaticamente definido como publicado? Não é possível, deve ser bug!

É meu caro! O Default Scope está cobrando seu preço, e a falta de testes no seu código também.

Como melhorar?

A primeira coisa que eu diria para você é: seja específico! Se quer buscar artigos publicados crie algo como:

class Article < ActiveRecord::Base
  scope :published, -> { where(published: true) }
end

Isso lhe permitirá consultar os artigos publicados assim:

Articles.published

Muito melhor, não!? E ainda, por não ser o padrão, não afetará a criação de novos artigos.

Conclusão

Consulte a documentação oficial. Além de ser o lugar correto para encontrar informações precisas é ótimo para evitar problemas.

No caso do default scope o Rails Guides não diz muito sobre o comportamento na criação de novos registros, sendo necessário consultar a documentação da API do Rails.

Referências

Logo Campus Code

Gostou desse conteúdo? Você pode aprender muito mais programando ao lado do Alan Batista e de outros desenvolvedores nos treinamentos do Campus Code. Nossos programas incluem os conteúdos mais pedidos pelo mercado como Ruby on Rails, Git, TDD, práticas ágeis, HTML 5, CSS e SQL.

Comentários