Rails 3:两个不同的布局,具有相同的控制器和动作?

时间:2011-12-29 06:16:36

标签: ruby-on-rails ruby-on-rails-3 layout controller action

假设您想要一个具有两种不同布局的博客。一个布局应该看起来像一个带有标题,页脚,菜单等的传统博客。另一个布局应该只包含博客文章,仅此而已。如何在不丢失与模型的连接的情况下执行此操作,强制执行和呈现仅一个操作并防止重复(DRY)?

posts_controller.rb

class PostsController < ApplicationController
  layout :choose_layout

  # chooses the layout by action name
  # problem: it forces us to use more than one action
  def choose_layout
    if action_name == 'diashow'
      return 'diashow'
    else
      return 'application'
    end
  end

  # the one and only action
  def index
    @posts = Post.all
    @number_posts = Post.count
    @timer_sec = 5

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end
  end

  # the unwanted action
  # it should execute and render the index action
  def diashow
    index # no sense cuz of no index-view rendering
    #render :action => "index" # doesn't get the model information
  end

  [..]
end

可能我想走错路,但我找不到合适的人。

更新

我的解决方案如下:

posts_controller.rb

class PostsController < ApplicationController
  layout :choose_layout

  def choose_layout
    current_uri = request.env['PATH_INFO']
    if current_uri.include?('diashow')
      return 'diashow'
    else
      return 'application'
    end
  end

  def index
    @posts = Post.all
    @number_posts = Post.count
    @timer_sec = 5

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end
  end

  [..]
end

配置/ routes.rb中

Wpr::Application.routes.draw do
  root :to => 'posts#index'

  match 'diashow' => 'posts#index'

  [..]
end

两条不同的路线指向同一位置(控制器/动作)。 current_uri = request.env['PATH_INFO']将url保存到变量中,以下if current_uri.include?('diashow')检查它是否是我们在 routes.rb 中配置的路由。

1 个答案:

答案 0 :(得分:1)

您可以根据特定条件选择要渲染的布局。例如,URL中的参数,正在呈现页面的设备等。

只需在choose_layout函数中使用该条件,而不是根据action_name决定布局。 <{1}}操作是不必要的。