Module: ControllerExtensions::GeneralMethods

Included in:
ActionController::Base
Defined in:
lib/controller_extensions/general_methods.rb

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/controller_extensions/general_methods.rb', line 3

def self.included(base)
  base.class_eval do
    const_set(:REDIRECT_DEFAULT_PATH, '/') unless const_defined?(:REDIRECT_DEFAULT_PATH)
    #Load resource or redirect to 404 if can't load resource. Used as before filter.
    #
    # Example:
    #
    #   class PermissionSetsController < ApplicationController
    #     before_filter :find_resource_or_404, :only => [:edit,:show, :destroy, :update] #it will find model as PermissionSet.find(params[:id])
    #
    # You can specify DB_MODEL constant in controller if controller name doesn't connects with model which it used.
    #
    #   DB_MODEL = :contact
    #
    # You can specify DB_SCOPE constant in controller if you need to find model in special scope.
    #
    #    DB_SCOPE = :sent
    # You can specify DB_ID_PARAM constant in controller if you pass to controller not id, but smth else.
    #
    #    DB_ID_PARAM = :contact_id
    #
    # You can specify DB_SCOPE and DB_MODEL together
    #
    #   class ContactsController < ApplicationController
    #     DB_MODEL = :contact
    #     DB_SCOPE = :sent
    #     DB_ID_PARAM = :contact_id
    #     before_filter :find_resource_or_404, :only => [:edit,:show, :destroy, :update] #it will find model as Contact.sent.find(params[:contact_id])
    #
    # Valid Options:
    #
    # * <tt>:only/:except</tt> - Passed to the <tt>before_filter</tt> call. Set which actions are verified.
    def find_resource_or_404
      model_name = defined?(self.class::DB_MODEL) ? self.class::DB_MODEL : controller_name.singularize
      model_to_find = defined?(self.class::DB_SCOPE) ? model_name.to_s.classify.constantize.send(self.class::DB_SCOPE) : model_name.to_s.classify.constantize
      id_from_param = defined?(self.class::DB_ID_PARAM) ? params[self.class::DB_ID_PARAM.to_sym] : params[:id]

      instance_variable_set("@#{model_name.to_s.underscore}", model_to_find.find(id_from_param))
    end

    #redirects to back.
    #!IMPORTANT to use this method you should add after_filter to your application_controller(after_filter :store_location)
    # You can specify REDIRECT_DEFAULT_PATH constant in ApplicationController to setup default redirect path(by default REDIRECT_DEFAULT_PATH='/')
    #
    # You can also pass params to redirect to method
    # Example
    # redirect_back_or_default :test_param => "test"
    def redirect_back_or_default(options = {})
      url = (session[:return_to] || ApplicationController::REDIRECT_DEFAULT_PATH)
      url = add_params_to_url(url, options)
      session[:return_to] = nil
      redirect_to url
    end

    #stores request path if request is get and not ajax
    #
    # Example
    # after_filter :store_location
    def store_location
      session[:return_to] = request.url if request.get? && !request.xhr? && controller_name != "sessions"
    end

    #add params to url. Prevent situation with identical param name
    #
    # Example:
    #   add_params_to_url('localhost:3000?test=3', {:test => 5, :asd => 2} #result will be  'localhost:3000?test=5&asd=2'
    def add_params_to_url(url, options)
      main_url, main_params = url.split('?')
      options = {} if options.nil?
      if main_params && main_params.split('&')
        main_params = Hash[main_params.split('&').map { |el| el.split("=") }]
        main_params = main_params.symbolize_keys
        options = options.symbolize_keys
        options = main_params.merge(options)
      end

      main_url + "#{'?' unless options.blank?}" + options.map { |key, value| "#{key}=#{value}" }.join("&")
    end
  end
end