2009-04-07 19 views

Respuesta

7

Todas estas soluciones usan find_by_name, lo que definitivamente requeriría tener un índice en esa columna y requerir que sean únicas. Una mejor solución que hemos utilizado, sacrificando una pequeña cantidad de belleza, es usar el prefijo del nombre del proveedor con su ID. Esto significa que no necesita tener un índice en su columna de nombre y/o requerir exclusividad.

vendor.rb

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

Así que esto le daría URL como

/1-Acme

/19-Safeway

etc

Luego, en su show acción todavía puede usar

Vendor.find(params[:id]) 

como el método implícitamente llamar .to_i en su argumento, y llamando to_i en una cadena tales siempre devolverá el prefijo numérico y soltar el restante en texto toda su pelusa en ese punto.

Lo anterior supone que está utilizando la ruta por defecto de /:controller/:action/:id, lo que haría que sus URL se ven como

/vendedores/mostrar/1-Acme

Pero si usted quiere que sólo se ven

/1-Acme

Entonces tienen una ruta como

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

Esto implicaría que tragaría una gran cantidad de URL que probablemente tampoco querría. Toma una advertencia.

+0

Hola, gracias por esto - ¿A qué te refieres con "tragar muchas URL que no te gustaría?" Oh, ¿te refieres a que la ruta cambiaría prácticamente cualquier cosa que te llame controlador? Estoy bien con los proveedores/show/1-Acme ... ¿cómo afecta el SEO? – AFG

+0

Sí, '/: id' coincidiría con muchas cosas, por lo que tendría que tener muchas rutas con nombre para '/ about', '/ contact', etc. En cuanto a SEO, creo que el prefijo de número es insignificante . –

+0

Entonces, ¿cómo crearía una ruta con nombre para vendedores/lista que correspondería a la acción en el control_de_vendedor.rb llamada 'lista'? Gracias. De lo contrario, se ve bien. – AFG

0

que tendría que experimentar un poco para hacer las cosas bien, pero hay dos partes principales para la solución.

1) Añadir una ruta. en config/rutas, añadir una línea que envía peticiones de la forma baseurl/controlador /: vendorname a la acción showsummary, (o tal vez una nueva acción, show_summary_by_vendor_name) [También, si pensaban utilizar baseurl /: vendorname , eso está bien también] Para mayor comodidad, asegúrese de que el parámetro sea similar a: nombre-proveedor, no el predeterminado: id

2) Escriba la acción del controlador. En el archivo de controlador, o bien editar su acción showsummary para distinguir a las basado en si se llama con un id o con un vendorname, o simplemente escribir show_summary_by_vendor_name. (dependiendo de las mejores prácticas, y qué ruta escribió en 1. No sé cuál es la mejor opción) Puede hacer @vendor = Vendors.find_by_name (params [: vendor_name]) o algo así, y luego renderízalo como lo harías en showsummary regulares.

3) usar eso como el enlace. Una vez que confirme que baseurl [/ controlador?]/Proveedor de nombres funciona, y muestra el resumen, asegúrese de que todos los enlaces en su aplicación, y en otros lugares, utilizan ese enlace. Por encima de mi cabeza, no puedo recordar lo difícil que es integrar una ruta personalizada en link_to, pero creo que es factible. La mayoría de los motores de búsqueda [google] dependen en gran medida de los enlaces, por lo que un buen SEO hará que uses esos enlaces con nombre, no los que están numerados. Creo. No sé mucho sobre SEO.

3

Ryan Bates tiene una gran screencast sobre este mismo tema.

Básicamente se sobrecarga el método to_param en el modelo de proveedor.

def to_param 
    permalink 
    end 

Luego, cuando se mira el recurso en su controlador que hacer algo como esto:

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

Pero el problema con esto es que usted tiene que asegurarse de que los nombres de los proveedores están único. Si no pueden ser, entonces haga la otra solución que Ryan sugiere, donde debe ingresar la identificación al nombre y luego analiza el uri resultante para encontrar la identificación del ítem.

1

Esto se hace mediante la modificación de las rutas que se utilizan para acceder a los URL y cambiarlas a utilizar: nombre, en lugar de: id. Esto probablemente significará que debe escribir las rutas usted mismo en lugar de depender de los recursos.

Por ejemplo añadir esto a las rutas.rb archivo:

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

El otro cambio que se requiere es que ahora tendrá que encontrar el objeto proveedor en la base de datos no el nombre del ello, por lo que:

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

Internamente (al menos para mi conocimiento/experimentación) cualquier nombre de parámetro no especificado en la parte de URL de la ruta (es decir, no dentro de la parte "/ Controller/Action /: id") se agrega al final como un parámetro.

6

Pensé que mencionaría String # parameterize, como complemento de la respuesta etiquetada.

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

Se va a filtrar los caracteres guión, sustituir los espacios con guiones etc.

+0

que es interesante ... ¿algún inconveniente? – AFG

+0

¡Todo tiene inconvenientes! Uno podría ser que el enlace cambiará automáticamente si cambia el atributo 'nombre', que puede controlarse más precisamente si almacena el enlace permanente en un atributo separado en la base de datos. –