Práticas recomendadas para lidar com rotas para subclasses de STI em trilhos
As visualizações e controladores do My Rails estão repletos deredirect_to
, link_to
eform_for
chamadas de método. As vezeslink_to
eredirect_to
são explícitos nos caminhos aos quais estão vinculando (por exemplo,link_to 'New Person', new_person_path
), mas muitas vezes os caminhos estão implícitos (por exemplo,link_to 'Show', person
)
Eu adiciono alguma herança de tabela única (STI) ao meu modelo (digamosEmployee < Person
) e todos esses métodos são interrompidos para uma instância da subclasse (por exemplo,Employee
); quando o rails é executadolink_to @person
, erros comundefined method employee_path' for #<#<Class:0x000001022bcd40>:0x0000010226d038>
. O Rails está procurando uma rota definida pelo nome da classe do objeto, que é empregado. Essas rotas de funcionários não são definidas e não há um controlador de funcionários, portanto, as ações também não são definidas.
Esta pergunta já foi feita antes:
AtStackOverflow, a resposta é editar todas as instâncias de link_to etc em toda a sua base de código e indicar o caminho explicitamenteEmStackOverflow novamente, duas pessoas sugerem o usoroutes.rb
para mapear os recursos da subclasse para a classe pai (map.resources :employees, :controller => 'people'
) A resposta principal nessa mesma pergunta de SO sugere a conversão de tipos de todos os objetos de instância na base de código usando.becomes
Ainda outro emStackOverflow, a resposta principal está no campo Do Repeat Yourself e sugere a criação de andaimes duplicados para cada subclasse.Aqui está a mesma pergunta novamente na SO, onde a resposta principal parece estar errada (a mágica do Rails simplesmente funciona!)Em outras partes da web, encontreiesta postagem no blog onde F2Andy recomenda editar o caminho em qualquer parte do código.Na postagem do blogHerança de tabela única e rotas RESTful no Logical Reality Design, é recomendável mapear os recursos da subclasse para o controlador da superclasse, como na resposta SO número 2 acima.Alex Reisner tem uma publicaçãoHerança de tabela única em trilhos, em que ele defende o mapeamento dos recursos das classes filho para a classe pai emroutes.rb
, pois isso apenas captura quebras de roteamento delink_to
eredirect_to
, mas não deform_for
. Portanto, ele recomenda adicionar um método à classe pai para fazer com que as subclasses mentam sobre a classe. Parece bom, mas o método dele me deu o erroundefined local variable or method `child' for #
.Portanto, a resposta que parece mais elegante e tem mais consenso (mas não é tudoeste elegante nemeste consenso), é adicionar os recursos ao seuroutes.rb
. Exceto que isso não funciona paraform_for
. Eu preciso de alguma clareza! Para destilar as opções acima, minhas opções são
routes.rb
(e espero não precisar chamar form_for em nenhuma subclasse)Substituir métodos internos dos trilhos para fazer com que as classes se encontremEdite todas as instâncias no código em que o caminho para a ação de um objeto é chamado de forma implícita ou explícita, alterando o caminho ou convertendo o objeto em tipo.Com todas essas respostas conflitantes, preciso de uma decisão. Parece-me que não há uma boa resposta. Isso é uma falha no design dos trilhos? Em caso afirmativo, é um bug que pode ser corrigido? Caso contrário, espero que alguém possa me esclarecer sobre isso, me guiar pelos prós e contras de cada opção (ou explicar por que isso não é uma opção) e qual é a resposta certa e por quê. Ou existe uma resposta certa que não estou encontrando na web?