【问题标题】:refactor "render format" in multiple controllers在多个控制器中重构“渲染格式”
【发布时间】:2012-01-22 16:00:59
【问题描述】:

所以我在多个控制器中有一个视图方法,它们看起来几乎完全相同:

  def show
    show! do |format|
      format.json do
        if @text.activated?
          @text.log
          render_for_api :texts_all, :json => @text
        else
          render :nothing => true
        end
      end
      format.pdf do
        pdf = QrPdf.new(@text)
        send_data pdf.render, filename: "text_#{@text.id}.pdf", type: "application/pdf"
      end
    end
  end

用于此的模型不同,但它们都具有在此方法中使用的相同属性(activatedlogid)。我还可以将render_for_api 给定的散列更改为当前为texts_alldocuments_all 等的散列,使其在任何地方都相同。

有没有办法在多个模型中使用此代码而不会产生大量重复?

感谢您的每一个提示! 特别是我发现很难处理do |format| 块。但我也不确定将代码放在哪里以及如何将其与不同类型的模型一起使用。

谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 refactoring controller


    【解决方案1】:

    如果模型是真正通用的:

    def show
      show_model @text
    end
    

    我不确定show! 是什么,但你可以弄清楚那部分。大致(未经测试):

    def show_model(obj)
      show! do |f|
        f.json do
          return render(:nothing => true) unless obj.activated?
    
          obj.log
          render_for_api :texts_all, :json => obj
        end
    
        f.pdf do
          opts = { filename: "text_#{obj.id}.pdf", type: "application/pdf" }
          send_data QrPdf.new(obj).render, opts
        end
      end
    end
    

    show_model 所在的位置而言,我倾向于将类似的东西放入基本控制器或混入中,但可能会有更好的选择。因为我通常有一个基本控制器,所以很容易把它放在那里。

    【讨论】:

    • 这也是我的答案!根据您的应用程序的大小/复杂性,我会将其作为私有方法放入 ApplicationController
    • show! 来自inherited_resources gem(github.com/josevalim/inherited_resources)。好的,你认为我可以把它放在我的 application_controller.rb 中吗?每个控制器都继承自这个控制器,好主意吗?
    • @choise 那里,或者你自己的基本控制器——但看起来inherited_resources 有它自己的基类,所以你的应用程序控制器需要扩展它,如果它还没有。也不知道基类方法的作用(! 方法),因此您需要确保它与任意模型兼容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2015-08-17
    • 1970-01-01
    相关资源
    最近更新 更多