Как переименовать идентификатор по умолчанию в param "id" в map.resources () Rails? - PullRequest
12 голосов
/ 01 мая 2009

Мне нравятся все маршруты по умолчанию, которые генерируются Rail's map.resources . Но есть случаи, когда я хотел бы использовать нечисловой идентификатор в моих маршрутах. Например, если вложенный маршрут состоит из пользователей и их статей, стандартный маршрут можно записать так:

map.resources :users, :has_many => [:articles] # => e.g. '/users/:id/articles/:id'

Однако есть много преимуществ / причин не использовать числовой идентификатор по умолчанию, сгенерированный Rails. Есть ли способ заменить параметры по умолчанию: id на другой канонический идентификатор по моему выбору, не приводя к записи пользовательских маршрутов для каждого стандартного действия? Скажите, если я хочу маршрут в следующем формате:

'/users/:login/articles/:id'

Достижим ли этот вид маршрутов, используя map.resources ?

Ответы [ 2 ]

13 голосов
/ 03 мая 2009

Начиная с Rails 2.3, невозможно изменить имя параметра и по-прежнему использовать автоматическую маршрутизацию, предоставляемую #resources.

В качестве обходного пути вы можете сопоставить articles с :path_prefix и :name_prefix:

map.resources :articles, :path_prefix => "/users/:login",
                         :name_prefix => "user_"

:path_prefix влияет на URL, а :name_prefix влияет на сгенерированные именованные маршруты, поэтому вы получите следующие маршруты:

    user_articles GET    /users/:login/articles(.:format)          {:controller=>"articles", :action=>"index"}
                  POST   /users/:login/articles(.:format)          {:controller=>"articles", :action=>"create"}
 new_user_article GET    /users/:login/articles/new(.:format)      {:controller=>"articles", :action=>"new"}
edit_user_article GET    /users/:login/articles/:id/edit(.:format) {:controller=>"articles", :action=>"edit"}
     user_article GET    /users/:login/articles/:id(.:format)      {:controller=>"articles", :action=>"show"}
                  PUT    /users/:login/articles/:id(.:format)      {:controller=>"articles", :action=>"update"}
                  DELETE /users/:login/articles/:id(.:format)      {:controller=>"articles", :action=>"destroy"}

Однако, как общее практическое правило, я бы придерживался соглашения по умолчанию Rails :user_id, с маршрутизацией, которую вы опубликовали в своем вопросе. Обычно считается, что :id и :user_id не обязательно подразумевают «числовой идентификатор» - они подразумевают «идентификатор ресурса», что бы это ни было. Придерживаясь соглашения по умолчанию, ваш код будет легче понять для всех, кто использовал маршруты ресурсов в Rails.

Чтобы использовать нечисловой идентификатор для ресурса, просто переопределите #to_param в вашей модели. Затем убедитесь, что в вашем контроллере используется искатель, который находит по этому идентификатору (а не по числовому идентификатору), например User#find_by_login!.

12 голосов
/ 01 мая 2009

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

class User < ActiveRecord::Base
  def to_param
    login
  end
end

user_articles_path(@user) => "/users/:login/articles"

Единственное другое изменение, которое вам нужно сделать, это найти пользователей по логину, а не по ID в ваших контроллерах.

...