Все эти решения использование find_by_name
, который определенно потребовал бы наличия индекса на том столбце и потребовал бы, чтобы они были уникальны. Лучшее решение, которое мы использовали, жертвуя небольшим количеством красоты, состоит в том, чтобы использовать префикс имя поставщика с его идентификатором. Это означает, что Вы не должны иметь индекса на своем столбце имени и/или потребовать уникальности.
vendor.rb
def to_param
normalized_name = name.gsub(' ', '-').gsub(/[^a-zA-Z0-9\_\-\.]/, '')
"#{self.id}-#{normalized_name}"
end
Таким образом, это дало бы Вам URL как
/1-Acme
/19-Safeway
и т.д.
Затем в Вашем выставочном действии можно все еще использовать
Vendor.find(params[:id])
поскольку тот метод будет неявно звонить .to_i
на его аргументе и вызове to_i
на такой строке будет всегда возвращать числовой префикс и отбрасывать оставшийся текст - его весь пух в той точке.
Вышеупомянутое предполагает использование маршрута по умолчанию /:controller/:action/:id
, который заставил бы Ваши URL быть похожими
/vendors/show/1-Acme
Но если Вы хотите, чтобы они просто посмотрели
/1-Acme
Затем имейте маршрут как
map.show_vendor '/:id', :controller => 'vendors', :action => 'show'
Это подразумевало бы, что это, это будет в значительной степени глотать много URL, что Вы, вероятно, не хотели бы это также. Возьмите предупреждение.
У Ryan Bates есть большой скринкаст на этом очень подвергающемся.
В основном Вы перегружаетесь to_param
метод в модели Vendor.
def to_param
permalink
end
Затем при поиске ресурса в контроллере, Вы делаете что-то вроде этого:
@vender = Vender.find_by_name(params[:id])
Но проблема с этим состоит в том, что необходимо будет удостовериться, что имена поставщиков уникальны. Если они не могут быть, затем делают другое решение, которое предлагает Ryan, где он предварительно ожидает идентификатор к имени и затем анализирует получающийся uri для нахождения идентификатора объекта.
Я думал, что упомяну String#parameterize как дополнение к теговому ответу.
def to_param
"#{id}-#{name.parameterize}"
end
Это отфильтрует написанные через дефис символы, пробелы замены с тире и т.д.
Вы делаете это путем изменения маршрутов, которые используются для доступа к ним URL и изменение их для использования: имя, а не: идентификатор. Это будет, вероятно, означать, что необходимо записать маршруты сами вместо того, чтобы полагаться на ресурсы.
Например, добавьте это к routes.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
Другое изменение, которое будет требоваться, - то, что теперь необходимо будет найти объект поставщика в базе данных именем не идентификатором, таким образом:
@vendor = Vendor.find_by_name(params[:name])
Внутренне (по крайней мере, к моему знанию/экспериментированию) независимо от того, что название параметра не указано в части URL маршрута (т.е. не в "/Controller/Action/:id" части его) прикрепляется на в конец в качестве параметра.
Дружественный идентификатор http://github.com/norman/friendly_id/blob/26b373414eba639a773e61ac595bb9c1424f6c0b/README.rdoc
Я должен был бы экспериментировать немного для разбираний в нем, но существует две основных части к решению.
1) Добавьте маршрут. в конфигурации/маршрутах добавьте строку, которая отправляет запросы формы baseurl/controller/:vendor-name к действию showsummary, (или возможно новому действию, show_summary_by_vendor_name) [также, если Вы запланировали использование baseurl/:vendorname, это прекрасно также] Для удобства, удостоверьтесь, что параметр - что-то как: имя поставщика, не значение по умолчанию: идентификатор
2) Запишите действие контроллера. В файле контроллера, или редактируют Ваше showsummary действие для дифференциации на основе того, называют ли это с идентификатором или с vendorname, или просто запишите show_summary_by_vendor_name. (в зависимости от лучших практик, и то, что направляет Вас, записало в 1. Я не знаю первое, что пришло на ум, который предпочтителен), можно затем сделать @vendor = Поставщики find_by_name (параметрические усилители [: vendor_name]) или что-то как этот, и затем представляет его способ, которым Вы были бы в регулярном showsummary.
3) Используйте это в качестве ссылки. После того как Вы подтверждаете что baseurl [/контроллер?]/vendor-name работает и показывает сводку, удостоверьтесь все ссылки в своем приложении, и в другом месте, используйте ту ссылку. Первое, что пришло на ум я не могу помнить, как трудный это должно интегрировать пользовательский маршрут в link_to, но я думаю, что это выполнимо. Большинство поисковых систем [Google] полагается в большой степени на ссылки, таким образом, хорошая SEO будет иметь Вас использующий те именованные ссылки, не пронумерованные. Я думаю. Я не знаю много о SEO.