2

Application Controller で index および show アクションのデフォルトの Respond_to を定義し、カスタマイズが必要な他のコントローラーでオーバーライドできるようにする方法はあるのでしょうか。

例があるとわかりやすいと思います。

InheritedResources、CanCan/Authlogic、および WickedPDF gem を使用して、pdf を生成し、ユーザーを承認しています。コードを乾かすことができるかどうか疑問に思っていました。

これが私が持っているものです

class ProductsController < InheritedResources::Base
  load_and_authorize_resource
  respond_to :html, :xml, :json, :pdf

  def index
    @products = Product.page(params[:page])
    index! do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end  

  def show
    show! do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end
end



class CustomersController < InheritedResources::Base
  def index
    index! do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end  

  def show
    show! do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end
end

これはうまくいきます。しかし、pdf を生成したいすべてのコントローラーで format.pdf を定義する必要があるのは冗長に思えます。これをアプリケーションコントローラーに移動するか、継承されたリソースを使用してどこかを指定し、コントローラーごとにこれをオーバーライドする方法はありますか? 何か案は?

ありがとうございました

4

1 に答える 1

2

わかりました、興味のある他の人のために次の解決策を思いつきました。

ApplicationController から継承する InheritedResources から継承するコントローラーを追加し、それから他のすべてのコントローラーを継承させることができると考えました (ただし、アプリケーション コントローラーから直接継承するいくつかの特殊なケースを除きます (HomeController のように、 index 以外のアクションはなく、特定のモデルに関連付けられていません) - このようにして、特定のデフォルトを定義できます - Respond_to などのすべてのコントローラーで使用し続け、InheritedResources gem の利点を引き続き享受します。

class DefaultInheritedResourcesController < InheritedResources::Base
  # For CanCan authorization - pretty much makes it application wide, without the need
  # to define it in each controller. Can still override it in ability.rb by making    
  # a resource readable to all users with a session.
  #  if user
  #    can :read, [Product]
  #  end 
  # Also for controllers that need special treatment, you can just inherit from ApplicationController
  # and override with skip_authorization_check - but for my app it's rare (only HomeController),
  # most of controllers deal with some kind of resource - so this is a useful convention for 99% of use cases. 

  load_and_authorize_resource 
  respond_to :html, :json, :xml, :pdf

  # format pdf needs to be redefined on those actions where index! or show! are called.
  def index
    super do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end  

  def show
    super do |format|
      format.pdf do
        render :pdf => pdf_file_name,
               :show_as_html => params[:debug].present?
      end
    end
  end  
end   

次に、私の ProductController でこれを行うことができます (私の ProductController がどこから継承されているかに注意してください。

class ProductsController < DefaultInheritedResourcesController
  def index
    @products = Product.page(params[:page])
    super
  end 
end

これが誰かを助けることを願っています。

于 2012-03-12T23:01:29.737 に答える