14

내 앱에 Foo와 Bar라는 두 가지 모델이 있다고 가정 해 보겠습니다.레일 네임 스페이스와 중첩 리소스

Foo 선택적으로 belongs_to Bar.

지금은 단일 Foo를 보거나 특정 Foo를 검색 할 수 있으며 FoosController가이 모든 것을 처리합니다. 내 URL은 다음과 같습니다. foos/1foos/new

가끔 바를보고 싶습니다. BarsController가이를 처리하면 다음과 같이 나타납니다. bars/1 또는 bars/1/edit.

내가 바를보고 있다면, 그 바의 모든 푸들을 탐색하고 싶을 수도 있습니다. 그래서, 그 Foos를 보시려면 bars/1/foos/을 사용하고 싶습니다.

이 중첩 된 자원이 매우 간단합니다, 그것은 다음과 같습니다 종류의 특별, 일반, FOOS에서 구별되는 바의 일부 그러나

resources :foo 
resources :bar do 
    resources :foo 
end 

, FOOS. 예를 들어, foos/1 또는 bars/1/foos/1을로드하면 동일한 Foo가 표시되지만 각 경우마다 다른 정보에 초점을 맞추고 있습니다.

그래서 Bar의 컨텍스트에있을 때 Foos를 처리하기 위해 BarFoos 컨트롤러가 있다고 생각했습니다. 그러나 Bar 아래에 BarFoos를 중첩하면 내 도우미는 bar_bar_foos_pathnew_bar_bar_foo_path과 같을 것입니다. 그건 불필요한 것처럼 보입니다.

이제 네임 스페이스에 대해 생각해 보았습니다. 내가 정의 할 수있는 레일 가이드에서 참조하십시오

namespace "bar" do 
    resources :foos 
end 

내가 app/bar/에서 두 번째 FoosController을 할 수 있으며, 그 FoosController이 bar_foo_path(:id) 대신 bar_bar_foo_path(:id)처럼 좋은 헬퍼와 바의 내부, FOOS을 처리 할 수있는 할 경우

.

하지만 그렇게하면 내 BarsController은 어떻게됩니까? resources :bars 대신 namespace "bar"이 있으면 요청은 어떻게 BarsController으로 라우팅 되나요?

마지막으로 최상위 FoosController와 이름 충돌이 일어나지 않도록 보조 FoosController 내부에서 수행해야 할 특별한 작업이 있습니까? 루팅이 "네임 스페이스"라는 것을 알았지 만 나머지 루비 코드는 app/bar/foos_controllerapp/foos_controller이 같은 클래스가 아니라는 것을 어떻게 알 수 있습니까?

감사합니다.

답변

36

나는 당신이 달성하려고하는 것은 생각 :

  1. 바는 많은 FOOS
  2. 보기, FOOS에 관계없이 부모의 모든 FOOS
  3. 보기 바 속하는있다.

경로를 통해 달성 할 수있는 경로는 입니다.RB : 당신이 결국

resources :foos 
resources :bars do 
    resources :foos, :controller => 'bars/foos' 
end 

경로 도우미는 다음과 같습니다

  • bars_path
  • foos_path
  • bars_foos_path
  • 등, 등, 나머지 에 대한 '레이크 노선'=)

결국 :

  • 앱/BarsController는
  • 앱/FoosController가
  • 앱/바 (g 컨트롤러 FOOS 레일) (g 컨트롤러 막대 레일)/FoosController (레일 g 컨트롤러 바/FOOS)

FoosController에서, 당신이 평소와 같이, FOOS 액세스합니다 :

@foos = Foos.all 

과 바에서을/FoosController, 당신은 바의 FOOS에 액세스 할 로 :이 도움이

before_filter :get_client 

private 
def get_client 
    @bar = Bar.find(params[:bar_id]) 
end 

희망 : 막대와 막대/FOOS 컨트롤러에 미리 검색 할 수 있습니다

@foos = @bar.foos 

. =)

편집 : 내 자원의 I 일부 하위 경로에서 검색 할 때 는 네임 스페이스 루트에 관해서는, 나는 개인적으로 사용했습니다. 나는 내 사이트의 관리자 섹션이있는 경우 예를 들어, 내가있을 수 있습니다 다음

routes.rb :

namespace :admin do 
    resources :foos 
end 

내가 내 컨트롤러를 만들 :

rails g controller admin/foos 

이 "내 사이트 url"/ admin/foos에서 액세스 할 수 있도록 내 foos 리소스를 설정하고 admin_foos_path와 같은 도우미도 얻습니다.

+0

, 그리고 당신의 대답은 매우 분명합니다, 감사합니다! 나는 당신의 대답이 어떻게 작동하는지 보았다. 그래서 그것은 굉장하다! 하나의 세부 사항을 추적하기 위해,이 시나리오에서 네임 스페이스를 중첩하는 것이 좋습니다. 어떤 방법 으로든 경험 한 단점/단점을 제공 할 수 있습니까? – Andrew

+3

당신의 경우 bar와 foo는 둘 다 리소스이고 foo는 bar에 속하기 때문에 중첩 된 리소스를 사용하는 것이 좋습니다. 위의 네임 스페이스 설명을 확장하려면 : 다른 컨텍스트에 대해 서로 다른 동작을 처리하는 상황, 즉 내가 관리자 인 경우 A, 그렇지 않으면 B를 수행하고 논리는 가장 단순하거나 흩어져 있으면 네임 스페이스를 고려하고 특정 컨텍스트에서 작동하도록 컨트롤러를 추가 할 것입니다. 'admin'은이 경우 리소스가 아닌 컨텍스트를 나타냅니다. – clemensp

+0

위대한, 그것은 많은 의미가 있습니다! – Andrew

5

이 접근 방식에는 단점이 있습니다.

상수를 선언하는 경우 CONST_NAME은 중첩 자원 foos에서 범위 알고리즘으로 인해 "초기화되지 않은 상수 :: Foo :: CONST_NAME"예외를 throw합니다.

그런 행동을 방지하려면, 사용

resources :foos 
resources :bars do 
    scope :module => "bar" do 
    resources :foos #, :controller => 'bar/foos' no need to use this now because route will be searched there by default 
    end 
end 

지금 당신은 예외을받지 않습니다 사용하는 동안 :

Foo::CONST_NAME 

또는

Bar::Foo::CONST_NAME 
내 시나리오 귀하의 설명을 정확히 맞다
관련 문제