【问题标题】:Rails set view to render in before_filterRails 将视图设置为在 before_filter 中渲染
【发布时间】:2015-04-07 02:56:03
【问题描述】:

是否可以设置从 before_filter 渲染的视图?

class ProductsController < ApplicationController
  before_filter :set_special_view


  def action1
    # some logic

    # i do not want to call render here
  end

  def action2
    # some logic

    # i do not want to call render here
  end

  private

  def set_special_view
    #self.class.view 'products/v1.html.erb' if some_cond?
    #self.class.view 'products/v2.html.erb' if anoter_cond?


    #self.class.layout :somelayout if some_cond?

  end
end

布局可以做为

self.class.layout :somelayout if some_cond?

有设置视图的方法吗?所以我在 before_filter 中设置了视图,我不触摸动作。

【问题讨论】:

  • 流程如下: 1. before_filter 运行哪个设置模板('products/view1.html.erb'); 2.动作运行(方法'action1')执行一些逻辑并设置@variables; 3. 渲染 before_filter 中指定的模板。

标签: ruby-on-rails rendering


【解决方案1】:

可以通过在我的控制器中覆盖 default_render 来完成:

class ProductsController < ApplicationController

before_filter :set_special_view


  def action1
    # some logic

  end

  def action2
    # some logic

  end

  def default_render(*args)
    unless @myview.nil?
      render @myview and return
    end

    super
  end


  private

  def set_special_view
    # decide which view to show here

    @myview = 'products/v1.html.erb' if cond1?
    @myview = 'products/v2.html.erb' if cond2?

  end
end

default_render 放在 'actionpack/lib/action_controller/metal/implicit_renderer.rb' 中只调用 render 而不带参数:

module ActionController
  module ImplicitRender
    def send_action(method, *args)
      ret = super
      default_render unless performed?
      ret
    end

    def default_render(*args)
      render(*args)
    end

    def method_for_action(action_name)
      super || if template_exists?(action_name.to_s, _prefixes)
        "default_render"
      end
    end
  end
end

在我们的 default_render 中,我们使用视图模板调用 render。

在此处查看 Rails 如何呈现模板 - http://climber2002.github.io/blog/2015/02/21/how-rails-finds-your-templates-part-1/

【讨论】:

    【解决方案2】:

    使用and return 在渲染后不运行任何逻辑。

    def set_special_layout
      #render 'products/v1' and return if some_cond?
      #render 'products/v2' and return if anoter_cond?
    
      #self.class.layout :somelayout if some_cond?
    
    end
    

    【讨论】:

    • 我确实想在渲染后运行逻辑。
    • # template = 'products/v1' if some_cond? # template = 'products/v2' if anoth_cond?那么在你的动作之后的逻辑,渲染模板模板应该是实例变量,抱歉不知道如何正确格式化
    • template = 'v1' 不起作用。它只是设置局部变量。我想找到将模板(视图)设置为呈现的方法。类似于 self.template = 'v1'。
    • 你试过在 set_special_layout 和 action 中都使用@template 吗?
    • @template 只是为我的控制器设置了一个实例变量。它不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 2018-10-27
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多