Changeset 1051
- Timestamp:
- 11/25/07 19:10:03 (1 year ago)
- Files:
-
- trunk/lib/merb/abstract_controller.rb (modified) (3 diffs)
- trunk/lib/merb/request.rb (modified) (4 diffs)
- trunk/spec/merb/controller_filters_spec.rb (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/lib/merb/abstract_controller.rb
r1047 r1051 184 184 # 185 185 def self.before(filter, opts={}) 186 raise(ArgumentError, 187 "You can specify either :only or :exclude but 188 not both at the same time for the same filter." 189 ) if opts.has_key?(:only) && opts.has_key?(:exclude) 190 191 opts = shuffle_filters!(opts) 192 193 case filter 194 when Symbol, String, Proc 195 (self.before_filters ||= []) << [filter, opts] 196 else 197 raise(ArgumentError, 198 'filters need to be either a Symbol, String or a Proc' 199 ) 200 end 186 add_filter((self.before_filters ||= []), filter, opts) 201 187 end 202 188 … … 208 194 # gain access to the response body like so: after Proc.new {|c| 209 195 # Tidy.new(c.body) }, :only => :index 196 210 197 def self.after(filter, opts={}) 198 add_filter((self.after_filters ||= []), filter, opts) 199 end 200 201 # Call #skip_before to remove an already declared (before) filter from your controller. 202 # 203 # Example: 204 # class Application < Merb::Controller 205 # before :require_login 206 # end 207 # 208 # class Login < Merb::Controller 209 # skip_before :require_login # Users shouldn't have to be logged in to log in 210 # end 211 212 def self.skip_before(filter) 213 skip_filter((self.before_filters || []), filter) 214 end 215 216 # Exactly like #skip_before, but for after filters 217 218 def self.skip_after(filter) 219 skip_filter((self.after_filters || []), filter) 220 end 221 222 def self.default_thrown_content 223 Hash.new{ |hash, key| hash[key] = "" } 224 end 225 226 # Set here to respond when rendering to cover the provides syntax of setting the content_type 227 def content_type_set? 228 false 229 end 230 231 def content_type 232 params[:format] || :html 233 end 234 235 private 236 237 def self.add_filter(filters, filter, opts={}) 211 238 raise(ArgumentError, 212 239 "You can specify either :only or :exclude but 213 240 not both at the same time for the same filter." 214 241 ) if opts.has_key?(:only) && opts.has_key?(:exclude) 215 242 216 243 opts = shuffle_filters!(opts) 217 244 218 245 case filter 219 246 when Symbol, Proc, String 220 (self.after_filters ||= []) << [filter, opts] 247 if existing_filter = filters.find {|f| f.first.to_s[filter.to_s]} 248 existing_filter.last.replace(opts) 249 else 250 filters << [filter, opts] 251 end 221 252 else 222 253 raise(ArgumentError, 223 ' After filters need to be either a Symbol, String or a Proc'254 'Filters need to be either a Symbol, String or a Proc' 224 255 ) 225 256 end 226 257 end 227 258 259 def self.skip_filter(filters, filter) 260 raise(ArgumentError, 261 'You can only skip filters that have a String or Symbol name.' 262 ) unless [Symbol, String].include? filter.class 263 264 MERB_LOGGER.warn("Filter #{filter} was not found in your filter chain." 265 ) unless filters.reject! {|f| f.first.to_s[filter.to_s] } 266 end 267 268 # Ensures that the passed in hash values are always arrays. 269 # 270 # shuffle_filters!(:only => :new) #=> {:only => [:new]} 271 228 272 def self.shuffle_filters!(opts={}) 229 273 if opts[:only] && opts[:only].is_a?(Symbol) … … 236 280 end 237 281 238 def self.default_thrown_content239 Hash.new{ |hash, key| hash[key] = "" }240 end241 242 # Set here to respond when rendering to cover the provides syntax of setting the content_type243 def content_type_set?244 false245 end246 247 248 def content_type249 params[:format] || :html250 end251 282 end 252 283 trunk/lib/merb/request.rb
r1050 r1051 23 23 request_method 24 24 when :post 25 m = body_and_query_params['_method'] 25 if self.class.parse_multipart_params 26 m = body_and_query_params.merge(multipart_params)['_method'] 27 else 28 m = body_and_query_params['_method'] 29 end 26 30 m.downcase! if m 27 31 METHODS.include?(m) ? m.to_sym : :post … … 66 70 h = query_params 67 71 h.merge!(body_params) if body_params 68 h 72 h.to_mash 69 73 end 70 74 end … … 74 78 begin 75 79 if Merb::Const::MULTIPART_REGEXP =~ content_type 76 self.class.parse_multipart(@body, $1, content_length) unless @body.size <= 0 80 if @body.size <= 0 81 {} 82 else 83 self.class.parse_multipart(@body, $1, content_length) 84 end 77 85 end 78 86 rescue ControllerExceptions::MultiPartParseError => e … … 102 110 def params 103 111 @params ||= begin 104 h = body_and_query_params. to_mash.merge(route_params)112 h = body_and_query_params.merge(route_params) 105 113 h.merge!(multipart_params) if self.class.parse_multipart_params && multipart_params 106 114 h.merge!(json_params) if self.class.parse_json_params && json_params trunk/spec/merb/controller_filters_spec.rb
r739 r1051 5 5 before :filter1 6 6 before :will_halt, :only => :four 7 8 before :overwrite_before_filter, :only => :two 9 after :overwrite_after_filter, :exclude => :four 10 11 after :after_will_be_skipped 12 before :before_will_be_skipped 13 7 14 before Proc.new {|c| c.one }, :exclude => [:one, :three, :uses_params] 8 15 after Proc.new {|c| c.five }, :exclude => [:one, :three, :uses_params] 9 16 after :filter2 10 17 before :modifies_param, :only => :uses_params 11 after :restores_param, :only => :uses_params 12 18 after :restores_param, :only => :uses_params 19 20 before :overwrite_before_filter, :only => :three 21 after :overwrite_after_filter, :exclude => [:one, :two, :uses_param] 22 23 skip_before :before_will_be_skipped 24 skip_after :after_will_be_skipped 25 26 # filters 13 27 14 28 def will_halt … … 38 52 @filter2='called' 39 53 end 40 54 55 def before_will_be_skipped 56 @before_skip='called' 57 end 58 59 def after_will_be_skipped 60 @after_skip='called' 61 end 62 63 def overwrite_before_filter 64 @overwrite_before_filter='called' 65 end 66 67 def overwrite_after_filter 68 @overwrite_after_filter='called' 69 end 70 71 # actions 72 41 73 def one 42 74 session.data.should == {} … … 90 122 end 91 123 92 end 124 end 125 93 126 describe "Dispatch and before/after filters" do 94 127 … … 185 218 end 186 219 end 187 188 end 220 221 it "should be overwritten by a subsequent call with the same filter" do 222 c = new_controller( 'two', TestFiltersController ) 223 c.dispatch(:two) 224 c.body.should == 'two' 225 c.instance_variable_get('@overwrite_before_filter').should == nil 226 c.instance_variable_get('@overwrite_after_filter').should == nil 227 228 c = new_controller( 'three', TestFiltersController ) 229 c.dispatch(:three) 230 c.body.should == 'three' 231 c.instance_variable_get('@overwrite_before_filter').should == 'called' 232 c.instance_variable_get('@overwrite_after_filter').should == 'called' 233 end 234 235 it "should not run if skipped" do 236 c = new_controller( 'one', TestFiltersController ) 237 c.dispatch(:one) 238 c.body.should == 'one' 239 c.instance_variable_get('@one').should == 'one' 240 c.instance_variable_get('@two').should == nil 241 c.instance_variable_get('@three').should == nil 242 243 c.instance_variable_get('@before_skip').should == nil 244 c.instance_variable_get('@after_skip').should == nil 245 end 246 247 it "should not allow skipping a filter that is not a symbol or string" do 248 ["before", "after"].each do |filter_type| 249 lambda { TestFiltersController.send('skip_'+filter_type, Proc.new{|c|puts c}) }.should raise_error(ArgumentError) 250 end 251 end 252 253 end
