Trilhos recursos RESTful usando to_param para um campo que contém caracteres separadores
-
09-09-2019 - |
Pergunta
Eu quero o meu Rails 2.3.2 app para responder e URLs geram assim:
/websites/asd.com
/websites/asd.com/dns_records/new
Na minha config / routes.rb, eu tenho:
map.resources :websites, :has_many => :dns_records
map.resources :dns_records, :belongs_to => :website
posso, então, acessar recursos tais como:
/websites/1
/websites/1/dns_records
Ao modificar meu modelo de site, eu posso gerar melhores URLs assim:
class Website < ActiveRecord::Base
def to_param
domain_name
end
...
end
# app/views/websites/index.erb
<% @websites.each do |w| %>
<%= link_to "Show #{w}", website_path(w) %>
<% end %>
# Produces a link to:
/websites/example_without_periods_in_name
No entanto, para nomes de domínio que contêm '' personagens, Rails fica infeliz. Eu acredito que este é porque o '. carácter é definido no ActionController :: Routing :: separadores, que lista os caracteres especiais para dividir a URL no. Isto permite-lhe fazer coisas como /websites/1.xml.
Assim, há uma maneira limpa para permitir '' caracteres em URLs RESTful?
Eu tentei redefinir ActionController :: Routing :: SEPARADORES para não incluir '', que é uma maneira totalmente ruim para resolver o problema. Este mexe-se URLs gerados por acrescentando ":. Formato". Para eles
Eu também sei que posso acrescentar: requisitos =>: '' {id => regexp} à minha config / routes.rb para corresponder a um nome de domínio que inclui (Sem isso, params [: id] está definido para a parte do nome de domínio antes do primeiro ''), mas isso não ajuda na geração de URLs / caminhos restfully
.Muito obrigado :) Nick
Solução
Resolvido o problema, com um grande agradecimento a http: //poocs.net/2007/11/14/special-characters-and-nested-routes (e veja http://dev.rubyonrails.org/ticket/6426 para referência adicional)
eu precisava para adicionar: requisitos => {: website_id => regexp} para cada rota aninhada que também estava indo para incluir um nome de domínio com períodos nele.
Aqui está a minha rota de trabalho:
map.resources :websites, :requirements => { :id => /[a-zA-Z0-9\-\.]+/ } do |websites|
websites.with_options :requirements => { :website_id => /[a-zA-Z0-9\-\.]+/ } do |websites_requirements|
websites_requirements.resources :dns_records
end
end
<%= link_to 'New DNS Record', new_website_dns_record_path(@website) %>
# Produces the URL
/websites/asd.com/dns_records/new
A chamada para
websites.with_options
é simplesmente de acordo com DRY de modo que: requisitos não tem que ser especificado para todas as rotas aninhadas para websites. Então, eu também poderia ter
websites_requirements.resources :accounts
websites_requirements.resources :monthly_bandwidth_records
etc.
Outras dicas
Esta é uma questão interessante. Eu não acho que você pode se livrar do mau '.:format'
anexado ao fim se você fizer um map.resources
básico. Se você quiser períodos nos nomes, você não está de acordo com os estilos trilhos habituais, e eu acho que uma rota personalizada poderia estar em ordem, se você absolutamente NECESSIDADE o '. na URL.
No entanto, talvez você deve considerar mudar sua definição de to_param
. O que você pensa sobre utilizando o seguinte?
def to_param
domain_name.sub('.','_dot_')
end
Eu acho que, se você estiver usando isso para gerenciar sites de clientes, é uma maneira bastante elegante para gerar agradável (e amigáveis ??SEO) URLs como
/websites/asd_dot_com/dns_records/new
/websites/asd_dot_com/
Eu tive um problema semelhante há algum tempo e chegou a uma solução similar. Usando /.+/ como a exigência para o param em questão funcionou bem para mim.
http://zargony.com/2009/05 / 05 / roteamento-parâmetros-com-um-ponto