ahoward (owner)

Revisions

gist: 34225 Download_button fork
public
Public Clone URL: git://gist.github.com/34225.git
Ruby
1
2
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# railsext.rb - my collection of rails hacks
#
 
 
# force const_missing to preload these classes - muckery
#
  ActionController
  ActionController::Base
  ActiveRecord
  ActiveRecord::Base
 
# support for using helper methods in controllers/models
#
  class Helper < ActionView::Base
    def Helper.list
      ActionView::Helpers.constants.grep(/Helper/i).map do |const|
        ActionView::Helpers.const_get(const)
      end
    end
 
    attr_accessor 'controller'
 
    def initialize controller = ( ActionController.current || ApplicationController.new ), *modules
      @controller = controller
 
      modules.push nil if modules.empty?
 
      modules.flatten.each do |mod|
        case mod
          when NilClass, :all, 'all'
            Helper.list.each{|helper| extend helper}
 
          when Module
            extend mod
 
          when Symbol, String
            mod = mod.to_s.underscore.sub(/helper$/, '')
            Helper.list.each do |helper|
              if mod == helper.name.underscore.sub(/helper$/, '')
                extend helper
              end
            end
 
          when Regexp
            Helper.list.each do |helper|
              if helper.name =~ mod
                extend helper
              end
            end
 
          else
            raise ArgumentError, mod.class.name
        end
      end
 
      extend @controller.master_helper_module if @controller
    end
 
    def session
      controller.session
    end
  end
 
  module ActionController
    class << self
      attr_accessor 'current'
    end
  end
 
  class ActionController::Base
    before_filter :setup_current_controller
    after_filter :teardown_current_controller
 
  protected
    def setup_current_controller
      ::ActionController.current = self
    end
    def teardown_current_controller
      ::ActionController.current = nil
    end
 
    def helper &block
      @helper = Helper.new(::ActionController.current || self)
      block ? @helper.instance_eval(&block) : @helper
    end
 
    def self.helper_import *methods
      methods.flatten.compact.each do |method|
        code = <<-code
def #{ method } *a, &b
helper{ #{ method }(*a, &b) }
end
protected '#{ method }'
code
        eval code
      end
    end
  end
 
  class ActiveRecord::Base
    def helper &block
      helper = Helper.new(::ActionController.current || ::ActionController::Base.new)
      block ? helper.instance_eval(&block) : helper
    end
  end
 
# support for immediate (throw/catch) base rendering methods
#
  class ActionController::Base
  protected
    def render! *a, &b
      render *a, &b unless a.empty? and b.nil?
      throw :render, self
    end
 
    def redirect_to! *a, &b
      redirect_to *a, &b
    ensure
      render!
    end
 
    def redirect_to_url! *a, &b
      redirect_to_url *a, &b
    ensure
      render!
    end
 
    def not_found! options = {}
      options = {:inline => options} if String == options
      options.to_options!
      unless options.has_key?(:inline) or options.has_key?(:text)
        options[:inline] = <<-html
<div style='padding:3em;color:#666;text-align:center;font-size:1.2em;'>
<p>
Sorry, but we could not find the page you are looking for.
</p>
<p style='color:#333'>
#{ h helper.url_for(request.request_uri) }
</p>
</div>
html
      end
      options[:status] ||= 404
      options[:layout] ||= 'application' unless options[:layout] == false
      render! options
    end
 
    def perform_action_without_filters
      if self.class.action_methods.include?(action_name)
        catch(:render){ send(action_name) }
        render unless performed?
      elsif respond_to? :method_missing
        catch(:render){ send(:method_missing, action_name) }
        render unless performed?
      elsif template_exists? && template_public?
        render
      else
        raise ::ActionController::UnknownAction, "No action responded to #{action_name}", caller
      end
    end
  end
 
# generic error classes used for model level application errors
#
  class ActiveRecord::Base
    class Error < ::ActiveRecord::ActiveRecordError; end
    class RecordNotFound < ::ActiveRecord::RecordNotFound; end
  end
 
# support for logging to the rails log from anywhere in the codebase
#
  class Object
    def log(*a, &b)
      logger = RAILS_DEFAULT_LOGGER
      if a.empty? and b.nil?
        logger
      else
        logger.info(*a, &b)
      end
    end
  end
 
# support for conditional excution based on rails_env
#
  class Object
    %w( test development production training ).each do |rails_env|
      module_eval <<-code
def #{ rails_env }? &block
if defined?(RAILS_ENV) and RAILS_ENV == '#{ rails_env }'
return( block ? block.call : true )
end
return false
end
code
    end
 
    def stage? &block
      if defined?(RAILS_STAGE) and RAILS_STAGE
        return( block ? block.call : true )
      end
      return false
    end
  end
 
# support for executing sql on the raw connection, getting back an array of
# results
#
  class Object
    def db(*a, &b)
      connection = ActiveRecord::Base.connection.raw_connection
      return connection if a.empty? and b.nil?
      adapter = ActiveRecord::Base.configurations[ RAILS_ENV ][ 'adapter' ].to_s
      case adapter
        when 'oci', 'oracle'
          cursor = connection.exec *a
          if b
            while row = cursor.fetch;
              b.call row
            end
          else
            returning [] do |rows|
              while row = cursor.fetch
                rows << row
              end
            end
          end
 
        when 'mysql', 'postgresql', 'sqlite'
          if b
            connection.query(*a).each do |row|
              b.call row
            end
          else
            returning [] do |rows|
              connection.query(*a).each do |row|
                rows << row
              end
            end
          end
 
      else
        raise ArgumentError, "#{ adapter } not implemented yet"
      end
    end
  end
 
# support for class level declarations of ActiveRecord default values for
# *new* records
#
  class ActiveRecord::Base
    class << self
      def defaults *argv, &block
        const_set(:Defaults, []) unless const_defined?(:Defaults)
        defaults = const_get(:Defaults)
 
        options =
          if block
            argv.flatten.inject({}){|h,k| h.update k => block}
          else
            case argv.size
              when 2
                { argv.first => argv.last }
              else
                argv.inject({}){|h,x| h.update x.to_hash}
            end
          end
        options.to_options!
 
        unless options.empty?
          options.each{|k,v| defaults << [k,v]}
          add_after_initialize_with_defaults! defaults
        end
 
        defaults
      end
 
      alias_method :default, :defaults
 
      def add_after_initialize_with_defaults! defaults = {}
        return if defined?(@add_after_initialize_with_defaults)
 
        after_initialize = instance_method(:after_initialize) rescue nil
 
        define_method(:after_initialize) do |*args|
          this = self
          after_initialize.bind(self).call(*args) if after_initialize
          return unless new_record?
          defaults.each do |key, value|
            value = instance_eval(&value) if value.respond_to?(:to_proc)
            write_attribute key, value
          end
        end
 
      ensure
        @add_after_initialize_with_defaults = true unless $!
      end
    end
  end
 
# support for indexing operator
#
  class ActiveRecord::Base
    def self.[](*args, &block)
      find(*args, &block)
    end
  end
 
# support for using named routes from the console - mega hack
#
  def use_named_routes! options = {}
    include ActionController::UrlWriter
    options.to_options!
    options.reverse_merge! :host => 'localhost', :port => 3000
    default_url_options.reverse_merge!(options)
  end
 
# top level methods to hook into above
#
  module Kernel
  private
    def transaction(*a, &b)
      ActiveRecord::Base.transaction(*a, &b)
    end
    def rollback!
      raise ActiveRecord::Rollback
    end
    def helper &block
      helper = Helper.new(::ActionController.current || ::ActionController::Base.new)
      block ? helper.instance_eval(&block) : helper
    end
  end