Сложная маршрутизация рельсов
-
19-09-2019 - |
Вопрос
Я хотел бы сделать что-то вроде github с вложенными URL-адресами и вроде Как маршрутизировать URL-адреса профилей пользователей, чтобы пропустить контроллер? но не совсем уверен, как с этим жить дальше.
Например, глядя на коммит, они имеют:':user/:repo/commit/:sha', с фиксацией контроллера.Как мне воспроизвести этот тип вложенного ресурса?
Спасибо :)
Решение
Если commit — это контроллер RESTful, который использует :sha вместо идентификатора для поиска записей.Вместо этого вы можете сделать это:
map.resource :commits, :path_prefix => ':user/:repo', :as => 'commit'
Он создаст стандартные маршруты RESTful, которые выглядят так http://yoursite.tld/:user/:repo/commit/:id
Опять же, если вы никогда не будете переводить часть id в URL-адресе в идентификатор фиксации, то нет причин, по которым вы не можете использовать ее в качестве значения :sha.
пример:
class CommitController < ApplicationController
def show
@commit = Commit.find(:first, :conditions => {:sha => params[:id]})
end
...
end
Вы также можете захотеть использовать to_param в модели фиксации, чтобы вернуть значение sha.
class Commt < ActiveRecord::Base
...
def to_param
sha
end
end
Так что теперь link_to commit_url(@commit, :user => current_user, :repo => @repo)
предоставит URL-адрес, соответствующий вашей схеме.
Другие советы
Как насчет
map.connect ':user/:repo/commit/:sha', :action => :index
Или используйте map.resource
вместо map.connect
если вам нужен маршрут RESTful.
В контроллере информацию URL можно получить из параметров, например params[:user]
возвращает имя пользователя.
Вы можете называть свои маршруты по своему усмотрению и указывать, с какими контроллерами и действиями вы хотите их использовать.
Например, у вас может быть:
map.connect ':user/:repo/commit/:sha', :controller => 'transactions', :action => 'commit'
Это отправит запрос методу фиксации в контроллере транзакций.
Доступ к другим переменным можно получить в вашем контроллере с помощью параметров:
@user = User.find(params[:user])
@repo = Repo.find(params[:repo])