Digamos que eu tenho um modelo Rails chamado Thing. O item tem um atributo de URL que pode opcionalmente ser definido como um URL em algum lugar da Internet. No código de exibição, preciso de uma lógica que faça o seguinte:
<% if thing.url.blank? %>
<%= link_to('Text', thing_path(thing)) %>
<% else %>
<%= link_to('Text', thing.url) %>
<% end %>
Essa lógica condicional na exibição é feia. Claro, eu poderia criar uma função auxiliar, que mudaria a visão para isso:
<%= thing_link('Text', thing) %>
Isso resolve o problema da verbosidade, mas eu realmente preferiria ter a funcionalidade no próprio modelo. Nesse caso, o código de exibição seria:
<%= link_to('Text', thing.link) %>
Obviamente, isso exigiria um método de link no modelo. Aqui está o que ele precisa conter:
def link
(self.url.blank?) ? thing_path(self) : self.url
end
Ao ponto da pergunta, thing_path () é um método indefinido dentro do código Model. Estou assumindo que é possível "puxar" alguns métodos auxiliares para o modelo, mas como? E existe um motivo real pelo qual o roteamento opera apenas no controlador e exibe as camadas do aplicativo? Posso pensar em muitos casos em que o código do modelo pode precisar lidar com URLs (integração com sistemas externos, etc.).
fonte
Respostas:
Nos Rails 3, 4 e 5 você pode usar:
por exemplo
fonte
:host
opção em qualquer lugar e defina-a uma vez nos arquivos de configuração do seu ambiente:Rails.application.routes.default_url_options[:host] = 'localhost:3000'
include Rails.application.routes.url_helpers
funciona para mim no Rails 4.1Eu encontrei a resposta sobre como fazer isso sozinho. Dentro do código do modelo, basta colocar:
Para Rails <= 2:
Para Rails 3:
Magicamente, isso
thing_path(self)
retorna o URL da coisa atual ouother_model_path(self.association_to_other_model)
retorna outro URL.fonte
include Rails.application.routes.url_helpers
Você também pode achar a seguinte abordagem mais limpa do que incluir todos os métodos:
fonte
undefined local variable or method 'url_helpers' for Event:Class
erro ... :(undefined method url_helpers
. O que eu vou fazer?class
, conforme mostrado na resposta. Se sua classe Model já estender< ApplicationRecord
isso não funcionará?Qualquer lógica relacionada ao que é exibido na exibição deve ser delegada a um método auxiliar, pois os métodos no modelo são estritamente para manipular dados.
Aqui está o que você poderia fazer:
fonte
Eu realmente gosto de seguir uma solução limpa.
É de http://hawkins.io/2012/03/generating_urls_whenever_and_wherever_you_want/
fonte
Embora possa haver uma maneira, eu tenderia a manter esse tipo de lógica fora do Modelo. Concordo que você não deve colocar isso em vista ( mantenha-o esbelto ), mas, a menos que o modelo esteja retornando um URL como um dado para o controlador, o material de roteamento deve estar no controlador.
fonte
(Editar: esqueça minha tagarelice anterior ...)
Ok, pode haver situações em que você iria para o modelo ou para algum outro URL ... Mas eu realmente não acho que isso pertença ao modelo, a exibição (ou talvez o modelo) parece mais apropriada.
Sobre as rotas, até onde eu sei, as rotas são para as ações nos controladores (que geralmente "usam magicamente" uma visualização), não diretamente nas visualizações. O controlador deve lidar com todas as solicitações, a visualização deve apresentar os resultados e o modelo deve manipular os dados e servi-los na visualização ou controlador. Já ouvi muitas pessoas falando sobre rotas para modelos (até o ponto em que estou começando a acreditar), mas como eu entendo: as rotas vão para os controladores. É claro que muitos controladores são controladores de um modelo e geralmente são chamados
<modelname>sController
(por exemplo, "UsersController" é o controlador do modelo "User").Se você se encontra escrevendo quantidades desagradáveis de lógica em uma exibição, tente mover a lógica para algum lugar mais apropriado; a lógica de solicitação e comunicação interna provavelmente pertence ao controlador, a lógica relacionada aos dados pode ser colocada no modelo (mas não a lógica de exibição, que inclui tags de link etc.) e a lógica puramente relacionada à exibição seria colocada em um auxiliar.
fonte