Вот гем, который хранит его в числовом формате, не требует миграций базы данных и изменений маршрутизации: https://github.com/namick/obfuscate_id
Я обнаружил, что этот драгоценный камень не работает вместе с некоторыми другими драгоценными камнями, особенно paper_trail. Это связано с тем, что он заменяет метод find
, а paper_trail вызывает find
с фактическим идентификатором записи.
Так что я использовал функциональность gem "scatter_swap", но не все остальное. Вот модель:
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
А в контроллере:
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
В качестве альтернативы перенаправлению, которое происходит там, вы можете просто включить канонический URL на странице. В перенаправлении есть ошибка игнорирования любых параметров запроса в URL. Это не было проблемой для моего проекта, так как у меня его не было. Но канонический URL был бы лучше.