Измените имя параметра: id в ресурсах маршрутизации для Rails

Я посмотрел вокруг, как изменить слот динамических параметров, и нашел этот пост, который делает именно то, что нужно. Сообщение https://thoughtbot.com/blog/rails-patch-change-the-name-of-the-id-parameter-in

В основном, что это делает, если следующие маршруты:

map.resources :clients, :key => :client_name do |client|
  client.resources :sites, :key => :name do |site|
    site.resources :articles, :key => :title
  end
end

Эти маршруты создают следующие пути:

/clients/:client_name
/clients/:client_name/sites/:name
/clients/:client_name/sites/:site_name/articles/:title

Одним из решений является переопределение метода def to_param в модели, но я хочу этого, не касаясь самой модели.

Но так как это для Rails 2.x, как я могу добиться того же для Rails 3?

Обновить

Это приложение использует Mongoid. Не AR. Таким образом, дружественный драгоценный камень не может быть использован afaik.

Ответ 1

Рельсы 4 и 5

В Rails 4 добавлена ​​опция :param, которая, похоже, делает именно то, что вы ищете. Вы можете посмотреть код Rails 3 по сравнению с кодом Rails 4.

Подробнее

Вы можете легко реализовать это в своем файле routes.rb:

# config/routes.rb

resources :posts, param: :slug

# app/controllers/posts_controller.rb

# ...
@post = Post.find_by(slug: params[:slug])
# ...

Начиная с выпуска Rails 4, эта функциональность задокументирована в Rails Guides.

Рельсы 3

К сожалению, в Rails 3 опция :key для resources была удалена, поэтому вы больше не можете легко изменять имя для маршрутов, созданных таким образом, просто передав дополнительную опцию.

Подробнее

Я предполагаю, что вы уже каким-то образом получили приложение, работающее так, как вы хотите, в прошлом году, но я пойду в путь, чтобы получить эффект, который вы описываете в Rails 3 в routes.rb. Это потребует немного больше работы, чем метод to_param. Вы можете определить пользовательские параметры в маршрутах, определенных с помощью scope и match (или это кузены get, put, post и delete)). Вы просто пишете в имени параметра, которое вы хотите в совпадении:

get 'clients/:client_name', :to => 'clients#show', :as => client

scope 'clients/:client_name' do
  get 'sites/:name', :to => 'sites#show', :as => site
end

Вам придется вручную добавить все маршруты, которые resources автоматически создает для вас, но он достигнет того, что вы ищете. Вы также можете эффективно использовать опцию :controller с scope и дополнительными блоками scope, чтобы вынуть часть повторения.


РЕДАКТИРОВАТЬ (8 мая 2014 г.): Сделайте более очевидным ответ, содержащий информацию для Rails 3 и 4. Обновите ссылки на код, чтобы перейти к точным номерам строк и зафиксировать их так, чтобы они должен работать в течение более длительного периода времени.

РЕДАКТИРОВАТЬ (16 ноября 2014 г.): Rails 4 должен быть наверху и включать релевантную информацию, поскольку это была текущая версия Rails в течение довольно долгого времени.

EDIT (9 августа 2016 г.):. Отразите, что решение по-прежнему работает в Rails 5 и обновляет устаревшие ссылки.

Ответ 2

в Rails 4, параметр pass param для изменения параметров: id. Например resources :photos, param: :photo_name будет генерировать /photos/: photo_name

Ответ 3

Если вы правильно поняли, что хотите, вместо id введите client_name в свой URL-адрес?

Вы можете сделать это, переопределив метод to_param в своей модели. Вы можете получить дополнительную информацию здесь.

Ответ 4

Там камень для этого, точно так же, как драгоценный камень для всего;)

Я использовал FriendlyId для такого поведения в рельсах 3.

Это потребует от вас добавить код в вашу модель, например:

class Client < ActiveRecord::Base
  has_friendly_id :name
end

... и если у ваших клиентов нет имен, совместимых с URI, вы можете использовать для этого пул, который вы можете сделать с помощью has_friendly_id :name, :use_slug => true. При использовании пули вам, очевидно, потребуется также сохранить их в базе данных.

И как уже упоминалось, вы все равно можете использовать трюк to_param с рельсами 3, как описано здесь. Я считаю, что FriendlyId более универсален, хотя.