Como a filosofia de convenção ao invés de configuração do Rails enganou um novato
Há cerca de 3 meses resolvi me aventurar no mundo da linguagem Ruby, embora estivesse curioso há um bom tempo, foi mais por necessidade do que curiosidade, e como não poderia deixar de ser, utilizando o framework Rails. Só tenho a dizer o quanto a dupla Ruby+Rails me surpreende a cada dia, mas não é por isso que deixarei de utilizar Java, prefiro trabalhar com ambas as linguagens, escolhendo a que melhor convier ao projeto, prazo, custo e hospedagem, mas esta história fica pra outro post.
Como todo novato, apanhei feio no início, e é claro ainda estou tropeçando, mas o que mais me fez rir foi não ficar atento a filosofia do Rails de “convenção ao invés de configuração”, ou seja, seguir padrões de nomes de métodos, classes, estrutura de diretórios, etc. Há um “jeito” certo de se estruturar o código seguindo esta filosofia, e quando você sai dela é que sua dor de cabeça começa, é normal encontrar pessoas zangadas com erros estranhos que só acontecem por não ter seguido as regras. As pessoas ficam bravas pois estão acostumados a seguir um modo rotineiro de estruturação. Bem estas pessoas que se adaptem às coisas novas. Pessoalmente se um framework segue “convenção ao invés de configuração” já consegue me atrair logo de cara pois eu entendo isso como “me faça ter menos trabalho pra utilizar você”.
O meu erro foi ter “apenas” criado no modelo uma coluna com nome “type”. O que eu não sabia, é que para o Rails, uma coluna “type”, é reservada automaticamente para salvar o class-name do objeto na tabela, para caso você necessitar de um modelo de herança simples. Vamos supor um objeto Cachorro e outro Gato, ambas descendem do objeto Animal, mas há uma única tabela (Animal) para salvar Cachorro e Gato, a coluna “type” seria automaticamente preenchida com o class-name correspondente do objeto, para que ao consultar o registro, o Rails saiba que objeto deve criar. Óbvio que esta não era minha intenção, após ver sucessivas vezes o erro “:in `instance_eval’: compile error” e consultar a documentação, descobri o motivo.
Não posso culpar o Rails, é um padrão dele, assim como outros nomes também são reservados como created_at e id, são os chamados MagicFieldNames. Resumindo: ao trabalhar com “convenção ao invés de configuração” lembrem-se sempre de olhar quais convenções são estas, vai te prevenir muitos erros e com certeza vai aumentar em muito sua produtividade, afinal o padrão está lá pra ser seguido.
Ah sim, caso você realmente precise de uma coluna chamada type para outros fins, basta sobrescrever o seguinte método no modelo:
def self.inheritance_column
“<nome da coluna a ser utilizada ao invés de type>”
end
Pronto, agora o Rails utilizará esta coluna para salvar o class-name e a type fica livre para fazer o que melhor convier, embora eu não recomende fazer isso.