Aquí es una joya que lo mantiene numérico, no requiere migraciones de bases de datos, y no hay cambios de enrutamiento: https://github.com/namick/obfuscate_id
he encontrado que esta joya no funciona en concierto con otras gemas, especialmente paper_trail. Esto se debe a la forma en que reemplaza el método find
, y paper_trail hace que se llame a find
con la identificación del registro real.
Así que he estado usando la funcionalidad "scatter_swap" de la gema, pero no el resto. Aquí está el modelo:
require 'obfuscate_id/scatter_swap'
class Page < ActiveRecord::Base
# This is a random number that, if changed, will invalidate all existing URLs. Don't change it!
@@obfuscate_spin = # random number here, which is essentially the encryption key
##
# Generate URL parameter to be used in the URL as the "id"
def to_param
# Use the obfuscate_id gem's class to "spin" the id into something obfuscated
spun_id = ScatterSwap.hash(self.id, @@obfuscate_spin)
# Throw any additional attributes in here that are to be included in the URL.
"#{spun_id} #{name}".parameterize
end
def self.find_by_slug!(slug)
spun_id = slug[/^[0-9]+/]
begin
find_by_id! ScatterSwap.reverse_hash(spun_id, @@obfuscate_spin)
rescue ActiveRecord::RecordNotFound => e
raise ActiveRecord::RecordNotFound, "Couldn't find matching Page."
end
end
end
Y en el controlador:
class PagesController < InheritedResources::Base
# Find the page using its URL slug
before_filter :find_page, except: [:index, :create, :new]
def find_page
@page = Page.find_by_slug! params[:id]
# If the URL doesn't match exactly, and this is a GET.
# We'll redirect to the new, correct URL, but if this is a non-GET, let's let them finish their request instead.
if params[:id] != @page.to_param && request.get?
redirect_to url_for({ id: @page.to_param }), status: 301
end
end
end
Como alternativa a la redirección que tiene lugar allí, simplemente podría incluir una URL canónica en la página. La redirección tiene el error de ignorar los parámetros de consulta en la URL. Esto no fue un problema para mi proyecto, ya que no tenía ninguno. Pero una URL canónica sería mejor.
Esto es increíble :) ¿Hay alguna forma de deshacerse del "==" adicional al final de la cadena cifrada? – Cyrus
Eso es parte del cifrado Base64, por lo que es necesario para descifrar la identificación. Podrías eliminarlo en el método 'encrypt' y agregarlo nuevamente en el método' decrypt', pero podría ser más propenso a error (ya que no estoy seguro de si Base64 * siempre * incluye ''==' al final de la cuerda). – siannopollo
Base64 rellena con '=' si el número de bits codificados no coincide exactamente. Habrá cero, uno o dos de ellos dependiendo de la duración de la entrada. – tadman