2009-05-01 4 views
12

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

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

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

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

этот вид маршрутов достижимо с помощью map.resources?

+0

p.s. Я прошу об этом, главным образом потому, что система маршрутизации Merb имеет такую ​​возможность. – newtonapple

ответ

13

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

В качестве временного решения можно сопоставить articles с :path_prefix и :name_prefix:

map.resources :articles, :path_prefix => "https://stackoverflow.com/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"} 

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

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

+0

+1: Очень хорошо написанный ответ. –

11

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

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

user_articles_path(@user) => "https://stackoverflow.com/users/:login/articles" 

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

+0

to_param делает попытку создания маршрутов. Но при распознавании он все равно передает его как: user_id. Оттуда переименовать его: login? – newtonapple

+0

Это хорошо написанный ответ на другой вопрос:/Вопрос здесь о маршрутизаторе и о том, как переименовать параметр маршрута ': id'. – Matchu

Смежные вопросы