Как переименовать параметр идентификатора по умолчанию в “id” в Rails'map.resources()?
-
03-07-2019 - |
Вопрос
Мне нравятся все маршруты по умолчанию, которые генерируются Rail карта.ресурсы.Но есть случаи, когда я хотел бы использовать нечисловой идентификатор в своих маршрутах.Например, если вложенный маршрут состоит из пользователей и их статей, стандартный маршрут может быть записан как таковой:
map.resources :users, :has_many => [:articles] # => e.g. '/users/:id/articles/:id'
Однако есть много преимуществ / причин не использовать числовой идентификатор по умолчанию, сгенерированный Rails.Есть ли способ заменить параметры default:id на другой канонический идентификатор по моему выбору, не приводя к написанию пользовательских маршрутов для каждого стандартного действия?Скажите, нужен ли мне маршрут в следующем формате:
'/users/:login/articles/:id'
Достижимы ли такого рода маршруты с использованием карта.ресурсы?
Решение
Начиная с 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!
.
Другие советы
Вы можете изменить значение по умолчанию для использования идентификатора в URL-адресах, переопределив значение to_param в вашей модели.например ,
class User < ActiveRecord::Base
def to_param
login
end
end
user_articles_path(@user) => "/users/:login/articles"
Единственное другое изменение, которое вам нужно будет внести, - это находить пользователей по логину, а не по идентификатору в ваших контроллерах.