File: app/controllers/admin/resource_controller.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Admin
  class: ResourceController#2
extends
  ResourceResponses ( Radiant )
inherits from
  ApplicationController   
has properties
method: index #46
method: destroy #67
class method: model_class (1/2) / 1 #72
class method: paginate_models / 1 #83
method: will_paginate_options #94
method: paginated? #101
method: pagination_parameters #109
method: rescue_action / 1 #120
method: model_class (2/E) #133
method: model #137
alias: current_object model #140
method: model= / 1 #141
method: load_model #144
method: models #152
alias: current_objects models #155
method: models= / 1 #156
method: load_models #159
method: model_name #163
method: plural_model_name #166
alias: models_name plural_model_name #169
method: model_symbol #171
method: plural_model_symbol #174
alias: models_symbol plural_model_symbol #177
method: humanized_model_name #179
method: continue_url / 1 #183
method: index_page_for_model #187
method: edit_model_path #196
method: announce_validation_errors #201
method: announce_removed #205
method: announce_not_found #210
method: announce_update_conflict #214
method: clear_model_cache #218
method: format_symbol #222
method: format #226
method: never_cache #233
method: populate_format #239

Class Hierarchy

Code

   1  require 'will_paginate'
   2  class Admin::ResourceController < ApplicationController
   3    extend Radiant::ResourceResponses
   4    
   5    helper_method :model, :current_object, :models, :current_objects, :model_symbol, :plural_model_symbol, :model_class, :model_name, :plural_model_name
   6    before_filter :populate_format
   7    before_filter :never_cache
   8    before_filter :load_models, :only => :index
   9    before_filter :load_model, :only => [:new, :create, :edit, :update, :remove, :destroy]
  10    after_filter :clear_model_cache, :only => [:create, :update, :destroy]
  11 
  12    cattr_reader :paginated
  13    cattr_accessor :default_per_page, :will_paginate_options
  14    
  15    responses do |r|
  16      # Equivalent respond_to block for :plural responses:
  17      # respond_to do |wants|
  18      #   wants.xml { render :xml => models }
  19      #   wants.json { render :json => models }
  20      #   wants.any
  21      # end
  22      r.plural.publish(:xml, :json) { render format_symbol => models }
  23 
  24      r.singular.publish(:xml, :json) { render format_symbol => model }
  25      r.singular.default { redirect_to edit_model_path if action_name == "show" }
  26      
  27      r.not_found.publish(:xml, :json) { head :not_found }
  28      r.not_found.default { announce_not_found; redirect_to :action => "index" }
  29 
  30      r.invalid.publish(:xml, :json) { render format_symbol => model.errors, :status => :unprocessable_entity }
  31      r.invalid.default { announce_validation_errors; render :action => template_name }
  32 
  33      r.stale.publish(:xml, :json) { head :conflict }
  34      r.stale.default { announce_update_conflict; render :action => template_name }
  35 
  36      r.create.publish(:xml, :json) { render format_symbol => model, :status => :created, :location => url_for(:format => format_symbol, :id => model) }
  37      r.create.default { redirect_to continue_url(params) }
  38 
  39      r.update.publish(:xml, :json) { head :ok }
  40      r.update.default { redirect_to continue_url(params) }
  41 
  42      r.destroy.publish(:xml, :json) { head :deleted }
  43      r.destroy.default { redirect_to continue_url(params) }
  44    end
  45 
  46    def index
  47      response_for :plural
  48    end
  49 
  50    [:show, :new, :edit, :remove].each do |action|
  51      class_eval %{
  52        def #{action}                # def show
  53          response_for :singular     #   response_for :singular
  54        end                          # end
  55      }, __FILE__, __LINE__
  56    end
  57 
  58    [:create, :update].each do |action|
  59      class_eval %{
  60        def #{action}                                       # def create
  61          model.update_attributes!(params[model_symbol])    #   model.update_attributes!(params[model_symbol])
  62          response_for :#{action}                           #   response_for :create
  63        end                                                 # end
  64      }, __FILE__, __LINE__
  65    end
  66 
  67    def destroy
  68      model.destroy
  69      response_for :destroy
  70    end
  71    
  72    def self.model_class(model_class = nil)
  73      @model_class ||= (model_class || self.controller_name).to_s.singularize.camelize.constantize
  74    end
  75 
  76    # call paginate_models to declare that will_paginate should be used in the index view
  77    # options specified here are accessible in the view by calling will_paginate_options
  78    # eg.
  79    #
  80    # Class MyController < Admin::ResourceController
  81    #   paginate_models :per_page => 100
  82 
  83    def self.paginate_models(options={})
  84      @@paginated = true
  85      @@will_paginate_options = options.slice(:class, :previous_label, :next_label, :inner_window, :outer_window, :separator, :container).merge(:param_name => :p)
  86      @@default_per_page = options[:per_page]
  87    end
  88 
  89    # returns a hash of options that can be passed to will_paginate
  90    # the @pagination_for@ helper method calls @will_paginate_options@ unless other options are supplied.
  91    #
  92    # pagination_for(@events)
  93    
  94    def will_paginate_options
  95      self.class.will_paginate_options || {}
  96    end
  97    helper_method :will_paginate_options
  98 
  99    # a convenience method that returns true if paginate_models has been called on this controller class
 100    # and can be used to make display decisions in controller and view
 101    def paginated?
 102      self.class.paginated == true && params[:pp] != 'all'
 103    end
 104    helper_method :paginated?
 105 
 106    # return a hash of page and per_page that can be used to build a will_paginate collection
 107    # the per_page figure can be set in several ways:
 108    # request parameter > declared by paginate_models > default set in config entry @admin.pagination.per_page@ > overall default of 50
 109    def pagination_parameters
 110      pp = params[:pp] || Radiant.config['admin.pagination.per_page']
 111      pp = (self.class.default_per_page || 50) if pp.blank?
 112      {
 113        :page => (params[:p] || 1).to_i, 
 114        :per_page => pp.to_i
 115      }
 116    end
 117 
 118    protected
 119 
 120      def rescue_action(exception)
 121        case exception
 122        when ActiveRecord::RecordInvalid
 123          response_for :invalid
 124        when ActiveRecord::StaleObjectError
 125          response_for :stale
 126        when ActiveRecord::RecordNotFound
 127          response_for :not_found
 128        else
 129          super
 130        end
 131      end
 132      
 133      def model_class
 134        self.class.model_class
 135      end
 136 
 137      def model
 138        instance_variable_get("@#{model_symbol}") || load_model
 139      end
 140      alias :current_object :model
 141      def model=(object)
 142        instance_variable_set("@#{model_symbol}", object)
 143      end
 144      def load_model
 145        self.model = if params[:id]
 146          model_class.find(params[:id])
 147        else
 148          model_class.new()
 149        end
 150      end
 151 
 152      def models
 153        instance_variable_get("@#{plural_model_symbol}") || load_models
 154      end
 155      alias :current_objects :models
 156      def models=(objects)
 157        instance_variable_set("@#{plural_model_symbol}", objects)
 158      end
 159      def load_models
 160        self.models = paginated? ? model_class.paginate(pagination_parameters) : model_class.all
 161      end
 162 
 163      def model_name
 164        model_class.name
 165      end
 166      def plural_model_name
 167        model_name.pluralize
 168      end
 169      alias :models_name :plural_model_name
 170 
 171      def model_symbol
 172        model_name.underscore.intern
 173      end
 174      def plural_model_symbol
 175        model_name.pluralize.underscore.intern
 176      end
 177      alias :models_symbol :plural_model_symbol
 178 
 179      def humanized_model_name
 180        t(model_name.underscore.downcase)
 181      end
 182 
 183      def continue_url(options)
 184        options[:redirect_to] || (params[:continue] ? {:action => 'edit', :id => model.id} : index_page_for_model)
 185      end
 186      
 187      def index_page_for_model
 188        parts = {:action => "index"}
 189        if paginated? && model && i = model_class.all.index(model)
 190          p = (i / pagination_parameters[:per_page].to_i) + 1
 191          parts[:p] = p if p && p > 1
 192        end
 193        parts
 194      end
 195 
 196      def edit_model_path
 197        method = "edit_admin_#{model_name.underscore}_path"
 198        send method.to_sym, params[:id]
 199      end
 200 
 201      def announce_validation_errors
 202        flash.now[:error] = t("resource_controller.validation_errors")
 203      end
 204 
 205      def announce_removed
 206        ActiveSupport::Deprecation.warn("announce_removed is no longer encouraged in Radiant 0.9.x.", caller)
 207        flash[:notice] = t("resource_controller.removed", :humanized_model_name => humanized_model_name)    
 208      end
 209      
 210      def announce_not_found
 211        flash[:notice] = t("resource_controller.not_found", :humanized_model_name => humanized_model_name)    
 212      end
 213 
 214      def announce_update_conflict
 215        flash.now[:error] =  t("resource_controller.update_conflict", :humanized_model_name => humanized_model_name)  
 216      end
 217 
 218      def clear_model_cache
 219        Radiant::Cache.clear if defined?(Radiant::Cache)
 220      end
 221 
 222      def format_symbol
 223        format.to_sym
 224      end
 225 
 226      def format
 227        params[:format] || 'html'
 228      end
 229      
 230      
 231      # I would like to set this to expires_in(1.minute, :private => true) to allow for more fluid navigation
 232      # but the annoyance for concurrent authors would be too great.
 233      def never_cache
 234        expires_now
 235      end
 236      
 237      # Assist with user agents that cause improper content-negotiation
 238      # warn "Remove default HTML format, Accept header no longer used. (#{__FILE__}: #{__LINE__})" if Rails.version !~ /^2\.1/
 239      def populate_format
 240        params[:format] ||= 'html' unless request.xhr?
 241      end
 242      
 243      
 244  end