액션 당 레일 레이아웃?


165

일부 작업 (대부분의 컨트롤러에서 새 작업)에 대해 다른 레이아웃을 사용합니다.

레이아웃을 지정하는 가장 좋은 방법이 무엇인지 궁금합니다. (동일한 컨트롤러에서 3 개 이상의 다른 레이아웃을 사용하고 있습니다)

나는 사용하는 것을 좋아하지 않는다

render : layout => '이름'

나는 일을 좋아

레이아웃 'name', : only => [: new]

그러나 2 개 이상의 다른 레이아웃을 지정하는 데 사용할 수 없습니다.

예를 들면 다음과 같습니다.

레이아웃 이름이 다르고 옵션 만 다른 동일한 컨트롤러에서 레이아웃을 두 번 호출하면 첫 번째 컨트롤이 무시됩니다. 지정된 액션에는 해당 액션이 표시되지 않습니다.

참고 : 저는 Rails 2를 사용하고 있습니다.


1
Rails Guides documentation : guides.rubyonrails.org/…
Kevin


2
(또한, 나는 미래 독자들을 돕기 위해이 안내서를 게시했습니다. 당신의 문제가 오래 전에 해결되었다는 것은 의심의 여지가 없습니다 ;-)
Kevin

답변:


297

방법을 사용하여 레이아웃을 설정할 수 있습니다.

class MyController < ApplicationController
  layout :resolve_layout

  # ...

  private

  def resolve_layout
    case action_name
    when "new", "create"
      "some_layout"
    when "index"
      "other_layout"
    else
      "application"
    end
  end
end

22
감사합니다. 그리고 누군가가 하나의 라이너로 더 간단한 일을하고 싶을 때 다음이 가능합니다. 컨트롤러 상단에서 쉽게 읽고 배치 할 수 있습니다. ---layout Proc.new{ ['index', 'new', 'create'].include?(action_name) ? 'some_layout' : 'other_layout' }
Holli

1
다양한 레이아웃에서 여러 다른 CSS 및 JS 파일을 각각 사용하는 경우 응용 프로그램 성능에 큰 영향을 미칩니 까?
노즈

15
-1 : 너무 복잡합니다. 아래 주석 ( stackoverflow.com/a/21203783/285154 )이 최선의 옵션입니다.
dimitarvp

감사! 이것은 많은 레벨에서 상속 컨트롤러를 사용하는 경우에만 Rails 4.2에서 여전히 문제입니다. 나는 이전에 방법을 사용했지만 지금 문제가 생겼을 때 테스트를 생각하지 않았습니다. 다시 감사드립니다.
244an

@dimitko 아니요, 질문 자체에서 이미 해당 솔루션을 참조했습니다. 3 가지 이상의 다른 레이아웃을 사용하려는 경우 작동하지 않습니다 (정확히 제 경우와 같습니다).
mrbrdo

201

두 레이아웃 중 하나만 선택하는 경우 다음을 사용할 수 있습니다 :only.

class ProductsController < ApplicationController
   layout "admin", only: [:new, :edit]
end

또는

class ProductsController < ApplicationController
   layout "application", only: [:index]
end

2
글쎄, 이것의 문제는 레이아웃을 조건부로 결정하기 위해 current_user와 같은 객체에 액세스 할 수 없다는 것입니다.
Andrew K

@AndrewK 동적으로 레이아웃을 선택하는 것은 질문의 일부가 아닌 것 같습니다.
Nick

11
질문 중 하나를 읽은 사람은 이미 질문 자체 에서이 솔루션을 설명하고 왜 내 경우 (3 개 이상의 레이아웃)에서 작동하지 않는지 알기 때문에 이것이 정답이 아니라는 것을 알 것입니다.
mrbrdo

2
mrbrdo가 말했듯이 이것은 대답이 아닙니다. 그의 질문은 구체적으로 나타냅니다 (I am using 3 or more different layouts in the same controller). 이 답변은 다른 레이아웃이 아닌 레이아웃을 허용합니다 .
Michael

49

respond_to를 사용하여 개별 액션의 레이아웃을 지정할 수 있습니다 .

  def foo
    @model = Bar.first
    respond_to do |format|
      format.html {render :layout => 'application'}
    end
  end

나에게 이것은 더 유연한 대답입니다. layout "[...]" to the controller class only allows one statement effectively. If you have more than two layouts to deal with (say, admin, generic_app, tailored_app), you will experience 렌더 및 / 또는 리다이렉트 를 적용하여 건조시키는 것은 이 동작 오류에서 여러 번 호출되었습니다. 이 제안을 사용하는 것 외에는 선택의 여지가 없습니다.
Jerome

1
이 답변은 switch 또는 if 문이있는 메서드를 사용하는 것과 달리 가장 단순하고 깔끔합니다.
kev

또한 erb 파일과 레이아웃을 모두 format.html { render 'custom_index', layout: 'application' } 같은 방식으로 지정할 수 있습니다 .
thatway_3

12

render를 사용하여 액션의 레이아웃을 지정할 수도 있습니다.

def foo
  render layout: "application"
end


7

컨트롤러에서 레이아웃을 지정하는 다양한 방법 :

  1. 다음 코드에서는 application_1 레이아웃이 인덱스에서 호출되고 사용자 컨트롤러의 조치 표시 및 다른 조치에 대해 애플리케이션 레이아웃 (기본 레이아웃)이 호출됩니다.

    class UsersController < ApplicationController
      layout "application_1", only: [:index, :show]
    end
  2. 다음 코드에서는 application_1 레이아웃이 Users 컨트롤러의 모든 작업에 대해 호출됩니다.

    class UsersController < ApplicationController
       layout "application_1"
    end
  3. 다음 코드에서는 application_1 레이아웃이 Users 컨트롤러의 테스트 작업에 대해서만 호출되고 다른 모든 작업에 대해서는 application 레이아웃 (기본값)이 호출됩니다.

        class UsersController < ApplicationController
          def test
            render layout: "application_1"
          end
        end

5

정밀성 :

실제로는 작동하지 않는 DRY 방식은 위에서 본 것이지만 정밀하게 작업해야합니다 ( "@some"). 같이 :

def your_action
   @some = foo
   render layout: "your_layout"
end

그리고 아닙니다 :

def your_action
   render layout: "your_layout"
   @some = foo
   @foo = some
end

before_action을 수행하면 작동하지 않습니다.

도움이 되길 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.