как сделать так, чтобы URL-адреса в Ruby on Rails дружили с SEO, зная @ vendor.name? - PullRequest
11 голосов
/ 07 апреля 2009

Мое приложение в RoR

У меня есть действие / представление, называемое showummary, где идентификатор был передан в URL, и контроллер использовал его для создания экземпляра @vendor, где @ vendor.name - это название компании.

Мне бы хотелось, чтобы URL-адрес был вместо того, чтобы указывать в / 1 / имя / vendor-name в URL-адресе.

Как мне это сделать?

Ответы [ 7 ]

7 голосов
/ 07 апреля 2009

Все эти решения используют 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 выглядят как

/ продавцы / шоу / 1-акме

Но если вы хотите, чтобы они просто смотрели

/ 1-Acme

Тогда есть маршрут как

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

Это будет означать, что это будет в значительной степени поглощать множество URL, которые вы, вероятно, тоже не захотите. Примите предупреждение.

6 голосов
/ 07 апреля 2009

Я думал, что упомяну String # parameterize, как дополнение к помеченному ответу.

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

Он отфильтрует дефисные символы, заменит пробелы тире и т. Д.

3 голосов
/ 07 апреля 2009

У Райана Бейтса есть отличная заставка на эту тему.

В основном вы перегружаете метод to_param в модели Vendor.

   def to_param
     permalink
   end

Затем, когда вы ищите ресурс в вашем контроллере, вы делаете что-то вроде этого:

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

Но проблема в том, что вам нужно убедиться, что имена поставщиков уникальны. Если они не могут быть, тогда сделайте другое решение, которое Райан предлагает, где он добавляет идентификатор к имени и затем анализирует полученное URI, чтобы найти идентификатор элемента.

1 голос
/ 07 апреля 2009
1 голос
/ 07 апреля 2009

Вы делаете это, изменяя маршруты, которые используются для доступа к этим URL-адресам, и изменяя их на использование: name, а не: id. Это, вероятно, будет означать, что вы должны сами писать маршруты, а не полагаться на ресурсы.

Например, добавьте это в файл rout.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"), прикрепляется до конца в качестве параметра.

0 голосов
/ 27 декабря 2010

Взгляните также на этот быстрый старт SEO для Rails

0 голосов
/ 07 апреля 2009

Я бы немного поэкспериментировал, чтобы понять это правильно, но есть две основные части решения.

1) Добавить маршрут. в config / маршруты добавьте строку, которая отправляет запросы вида baseurl / controller /: vendor-name к действию showummary, (или, возможно, к новому действию, show_summary_by_vendor_name) [также, если вы планируете использовать baseurl /: vendorname, это тоже хорошо] Для удобства убедитесь, что параметр выглядит примерно так: имя-поставщика, а не значение по умолчанию: id

2) Запишите действие контроллера. В файле контроллера либо отредактируйте свое действие showummary для различения в зависимости от того, вызывается ли оно с идентификатором или с именем поставщика, либо просто напишите show_summary_by_vendor_name. (в зависимости от лучших практик и того, какой маршрут вы написали в 1. Я не знаю, что лучше) Вы можете тогда сделать @vendor = Vendors.find_by_name (params [: vendor_name]) или что-то в этом роде, а затем визуализируйте его так, как вы бы делали это в обычных выставках.

3) Используйте это как ссылку. Как только вы подтвердите, что baseurl [/ controller?] / Vendor-name работает и показывает сводку, убедитесь, что все ссылки в вашем приложении и в других местах используют эту ссылку. Я не могу вспомнить, насколько сложно интегрировать пользовательский маршрут в link_to, но я думаю, что это выполнимо. Большинство поисковых систем [google] в значительной степени полагаются на ссылки, поэтому в хорошем SEO вы будете использовать эти именованные ссылки, а не нумерованные. Я думаю. Я не знаю много о SEO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...