2009-04-07 11 views

risposta

7

Tutte queste soluzioni utilizzano find_by_name, che richiederebbe sicuramente un indice su tale colonna e richiedono che siano univoci. Una soluzione migliore che abbiamo usato, sacrificando una piccola quantità di bellezza, è quella di usare il prefisso del nome del venditore con il suo ID. Ciò significa che non è necessario avere un indice sulla colonna del nome e/o richiedere unicità.

vendor.rb

def to_param 
    normalized_name = name.gsub(' ', '-').gsub(/[^a-zA-Z0-9\_\-\.]/, '') 
    "#{self.id}-#{normalized_name}" 
end 

Quindi questo darebbe URL come

/1-Acme

/19-Safeway

ecc

Poi, nel vostro show azione che è ancora possibile utilizzare

Vendor.find(params[:id]) 

come tale metodo implicitamente chiamare .to_i sul suo argomento, e chiamando to_i su tale stringa restituirà sempre il prefisso numerico e rilasciare il restante testo-è tutto fluff in quel punto.

È possibile che questo presuppone che si sta utilizzando il percorso di default di /:controller/:action/:id, che renderebbe i tuoi URL assomigliano

/fornitori/show/1-Acme

Ma se si vuole loro di guardare solo

/1-Acme

Poi hanno un percorso simile

map.show_vendor '/:id', :controller => 'vendors', :action => 'show' 

Ciò implicherebbe che sarebbe ingoiare un sacco di URL che probabilmente non lo vorremmo. Fai attenzione

+0

Ciao, grazie per questo - cosa intendi con "inghiottire un sacco di URL che non vorresti fosse?" oh, vuoi dire che il percorso cambierebbe praticamente qualsiasi cosa chiamasse quel controller, intendi? Io sto bene con i venditori/show/1-Acme ... come influisce sul SEO? – AFG

+0

Sì, '/: id' corrisponderebbe a molte cose, quindi dovresti avere molti percorsi con nome per '/ about', '/ contact', ecc. Per quanto riguarda il SEO, penso che il prefisso del numero sia trascurabile . –

+0

Quindi, come potrei creare una rotta denominata per i fornitori/elenco che corrisponderebbe all'azione nel vendor_controller.rb chiamata 'lista'? Grazie. Altrimenti sembra buono. – AFG

0

Dovrei provare un po 'per farlo bene, ma ci sono due parti principali della soluzione.

1) Aggiungere un percorso. in config/routes, aggiungi una linea che invii richieste del modulo baseurl/controller /: nome-vendor all'azione showummary, (o forse una nuova azione, show_summary_by_vendor_name) [inoltre, se hai pianificato l'uso di baseurl: vendorname Per comodità, assicurarsi che il parametro sia simile al nome del fornitore, non al valore predefinito: id

2) Scrivere l'azione del controller. Nel file del controller, modifica la tua azione di rendering in modo da differenziare in base al fatto che venga chiamato con un id o con un vendorname, o semplicemente scrivi un show_summary_by_vendor_name. (a seconda delle migliori pratiche, e quale percorso hai scritto in 1. Non so in cima alla mia testa che è preferibile) Puoi quindi fare @vendor = Vendors.find_by_name (params [: vendor_name]) o qualcosa del genere, e poi renderlo come si farebbe in un normale show.

3) Utilizzare come collegamento. Una volta confermato che baseurl [/ controller?]/Nome del fornitore funziona e mostra il riepilogo, assicurarsi che tutti i collegamenti nell'applicazione e altrove utilizzino tale collegamento. In cima alla mia testa, non ricordo quanto sia difficile integrare un percorso personalizzato in link_to, ma penso che sia fattibile. La maggior parte dei motori di ricerca [google] fanno molto affidamento sui link, quindi una buona SEO ti farà utilizzare i link con i nomi, non quelli numerati. Credo. Non so molto di SEO.

3

Ryan Bates ha un ottimo screencast proprio su questo argomento.

Fondamentalmente si sovraccarica il metodo to_param nel modello fornitore.

def to_param 
    permalink 
    end 

Poi, quando si guarda la risorsa nel controller si fa qualcosa di simile:

@vender = Vender.find_by_name(params[:id]) 

Ma il problema di questo è che si dovrà fare in modo che i nomi dei venditori sono unico. Se non possono essere allora fai l'altra soluzione che Ryan suggerisce dove antepone l'id al nome e poi analizza l'uri risultante per trovare l'id dell'oggetto.

1

Si esegue questa operazione modificando i percorsi utilizzati per accedere a tali URL e modificandoli per l'utilizzo: nome, anziché: id. Questo probabilmente significa che devi scrivere le rotte da solo piuttosto che fare affidamento sulle risorse.

Ad esempio, aggiungere questo ai percorsi.file di RB:

map.with_options :controller => "vendor" do |vendor| 
    vendor.connect "/vendor/:name", :action => "show" 
    # more routes here for update, delete, new, etc as required 
end 

L'altro cambiamento che sarà richiesto è che ora si dovrà trovare l'oggetto fornitore nella banca dati dal nome, non l'id, in modo da:

@vendor = Vendor.find_by_name(params[:name]) 

internamente (almeno alla mia conoscenza/sperimentazione) qualunque parametro il nome non è specificato nella parte URL della rotta (cioè non all'interno della parte "/ Controller/Azione /: id" di esso) viene aggiunto alla fine come parametro.

6

Ho pensato di menzionare Parametro String # come supplemento alla risposta codificata.

def to_param 
    "#{id}-#{name.parameterize}" 
end 

Sarà filtrare personaggi sillabate, sostituire gli spazi con dei trattini ecc

+0

questo è interessante ... qualsiasi aspetto negativo? – AFG

+0

Tutto ha lati negativi! Uno potrebbe essere che il collegamento cambierà automaticamente se cambia l'attributo 'nome', che può essere controllato in modo più preciso se si memorizza il permalink in un attributo separato nel database. –