Rails 용 라우팅 리소스에서 : id 매개 변수의 이름 변경


107

동적 매개 변수 슬롯을 변경하는 방법을 둘러 보았고 정확한 작업을 수행하는이 게시물을 찾았습니다. 게시물은 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에서도 동일한 결과를 얻을 수 있습니까?

최신 정보

이 앱은 몽고 이드를 사용하고 있습니다. AR이 아닙니다. 따라서 친절한 보석은 afaik으로 사용할 수 없습니다.

답변:


192

레일 4 및 5

Rails 4에서 :param옵션이 추가되었는데, 이것은 당신이 찾고있는 것을 정확히하는 것 같습니다. Rails 4 코드 와 비교 하여 Rails 3 코드를 살펴볼 수 있습니다 .

세부

routes.rb파일 에서 쉽게 구현할 수 있습니다 .

# config/routes.rb

resources :posts, param: :slug

# app/controllers/posts_controller.rb

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

Rails 4가 출시 될 때이 기능은 Rails 가이드에 문서화되어 있습니다.

레일스 3

불행히도 Rails 3에서는에 대한 :key옵션 resources이 제거 되었기 때문에 추가 옵션을 전달하는 것만으로는 더 이상 이런 방식으로 생성 된 경로의 이름을 쉽게 변경할 수 없습니다.

세부

저는 여러분이 작년에 여러분이 원하는 방식으로 애플리케이션을 이미 어떻게 든 작동 시켰다고 가정하지만, Rails 3에서 설명한 효과를 얻을 수있는 방법에 대해 설명하겠습니다 routes.rb. to_param방법 보다 약간 더 많은 작업이 필요합니다 . 당신은 여전히 루트 사용자 지정 매개 변수를 사용하여 정의 정의 할 수 있습니다 scopematch(또는 그것의 사촌 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과 함께 옵션을 효과적으로 사용하여 일부 반복을 제거 할 수 있습니다.scopescope


수정 (2014 년 5 월 8 일) : 답에 Rails 3 및 4에 대한 정보가 포함되어 있음을 더 분명하게 만드십시오. 코드 링크를 업데이트하여 정확한 줄 번호로 이동하고 커밋하여 더 오랜 기간 동안 작동하도록합니다.

수정 (2014 년 11 월 16 일) : Rails 4가 현재 최상위에 있어야하며 현재 Rails의 현재 버전이었던만큼 관련 정보를 포함해야합니다.

편집 (2016 년 8 월 9 일) : 솔루션이 여전히 Rails 5에서 작동한다는 것을 반영하고 오래된 링크를 업데이트합니다.


1
따라서 기본적으로 Rails3는 라우터에 리소스 옵션을 생성하여 나머지를 채울 수 있지만 사용자 지정 변수 이름을 갖기 위해 재정의해야합니다.
Augustin Riedinger 2013

1
다음 param은 레일 3 옵션 의 백 포트입니다 . gist.github.com/sj26/44ef47fe8b98b46ee32d
sj26

이것은 url 헬퍼를 깨뜨립니다. 객체를 전달하거나 슬러그를 전달하면 누락 된 [: slug] 키에 대해 불평하면 일반 ID 기반 경로가 생성됩니다. 해결 방법에 대한 아이디어가 있습니까?
RonLugge 2014

9
참고로, 중첩 된 리소스를 사용하는 경우 부모 리소스의 매개 변수는 post_slug이므로 혼동 될 수 있습니다.
ghayes

4
이것은 정말 좋지만 중첩 리소스에 대해 post_post_id와 같은 부모 ID의 매개 변수 이름을 원하지 않으면 어떻게해야합니까?
Asnad 아타

45

Rails 4에서는 param 옵션을 전달하여 : id 매개 변수를 변경합니다. 예를 들어 resources :photos, param: :photo_name/ photos / : photo_name을 생성합니다.


1

내가 당신을 올바르게 이해한다면, 당신이 원하는 것은 당신의 URL client_name대신에 갖는 것입니다 id.

to_param모델 에서 메서드를 재정 의하여이를 수행 할 수 있습니다 . 여기에서 자세한 정보를 얻을 수 있습니다 .


1
이미 언급했듯이 모델을 변경하지 않는 제약이 있습니다. 앞서 언급 한 예제가 Rails 3에서 지원되지 않거나 더 이상 사용되지 않습니까?
Autodidact 2011-07-06

1

모든 것을위한 보석이있는 것처럼 그것을위한 보석이 있습니다;)

저는 Rails 3에서 이런 종류의 동작을 위해 FriendlyId 를 사용하고 있습니다.

하지만 다음과 같이 모델에 몇 가지 코드를 추가해야합니다.

class Client < ActiveRecord::Base
  has_friendly_id :name
end

... 클라이언트에 URI 호환 이름이없는 경우이를 위해 슬러그를 사용할 수 있습니다 has_friendly_id :name, :use_slug => true. 슬러그를 사용할 때는 당연히 데이터베이스에도 유지해야합니다.

이미 언급했듯이 여기에to_param 설명 된대로 레일 3 에서 트릭을 계속 사용할 수 있습니다 . 나는 FriendlyId가 조금 더 다재다능하다고 생각합니다.


나는 친절한 ID를 좋아하고 많은 프로젝트에서 사용했습니다. 실제로 내 앱은 Mongoid를 사용하고 있습니다. 그리고 friendly_id는 그것을 지원하지 않습니다. 그리고 이미 언급했듯이 내 제약은 모델을 변경하지 않는 것입니다.
Autodidact 2011-07-06

1
mongoid를 사용 하는 경우이 기능을 달성하기위한 mongoid-slug 가 있습니다. 실제로를 사용 to_param하지만 백그라운드에서 다른 영리한 작업도 수행합니다. 여기 링크를 발견 stackoverflow.com/questions/4744446/...
프로스트

나는 그 보석을 좋아했다. 또 다른 유사한 슬러 고 이드가 있습니다. 그러나 내가 말했듯이 모델을 수정하지 않는 제약이 있습니다. 그것은 to_param앱의 내 프런트 엔드 부분을 망가 뜨립니다. 실제로 라우팅 접근 방식을 필사적으로 찾고 있는데, API를 변경해야하지만 앱에서 모델 및 프런트 엔드 부분을 분리하지 않고 있습니다. 내가 언급 한대로 경로 만 수정하고 위의 이전 버전의 레일에 대한 예제 게시물 만 수정하는 방법을 사용할 수없는 이유는 무엇입니까 ???
Autodidact 2011-07-07

사용자 지정 경로 키를 사용하도록 컨트롤러를 다시 작성해 보셨습니까? 예를 들어, @client = Client.find(:name => param[:client_name]ClientsController#show? 작동 할 수 있습니다.
프로스트

Client.where(:name => param[:client_name]).first, 그건.
프로스트

0

Rails 3에서는 다음과 같은 네임 스페이스와 범위의 조합을 사용하여 id 키의 이름을 바꿀 수 있습니다.

namespace :clients do
  scope "/:client_name" do
    namespace :sites do
      scope "/:name" do
         post "/:title" => "articles#create"
         ...
      end
    end
  end
end
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.