Skip to content

Commit

Permalink
Make it a module rather than monkey patching directly
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Delcambre committed Aug 23, 2009
1 parent f11b8ab commit 2e6efcc
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 53 deletions.
83 changes: 46 additions & 37 deletions lib/rails_action_args/abstract_controller.rb
@@ -1,44 +1,53 @@
class AbstractController::Base

class << self
attr_accessor :action_argument_list
alias_method :old_inherited, :inherited
module ActionArgs

# Stores the argument lists for all methods for this class.
#
# ==== Parameters
# klass<Class>::
# The controller that is being inherited from Merb::AbstractController.
def inherited(klass)
klass.action_argument_list = Hash.new do |h,k|
args = klass.instance_method(k).get_args
arguments = args[0]
defaults = []
arguments.each {|a| defaults << a[0] if a.size == 2} if arguments
h[k] = [arguments || [], defaults]
def self.included(base)

base.class_eval do
class << self
attr_accessor :action_argument_list
alias_method :old_inherited, :inherited

# Stores the argument lists for all methods for this class.
#
# ==== Parameters
# klass<Class>::
# The controller that is being inherited from Merb::AbstractController.
def inherited(klass)
klass.action_argument_list = Hash.new do |hash,action|
args = klass.instance_method(action).get_args
arguments = args[0]
defaults = []
arguments.each {|a| defaults << a[0] if a.size == 2} if arguments
hash[action] = [arguments || [], defaults]
end
old_inherited(klass)
end
end
old_inherited(klass)
end
end

alias :old_send_action :send_action
# Calls an action and maps the params hash to the action parameters.
#
# ==== Parameters
# action<Symbol>:: The action to call
#
# ==== Raises
# BadRequest:: The params hash doesn't have a required parameter.
def send_action(action)
arguments, defaults = self.class.action_argument_list[action.to_s]

# Calls an action and maps the params hash to the action parameters.
#
# ==== Parameters
# action<Symbol>:: The action to call
#
# ==== Raises
# BadRequest:: The params hash doesn't have a required parameter.
def send_action(action)
arguments, defaults = self.class.action_argument_list[action]

args = arguments.map do |arg, default|
p = params.key?(arg.to_sym)
unless p || (defaults && defaults.include?(arg))
missing = arguments.reject {|arg| params.key?(arg[0].to_sym || arg[1])}
raise BadRequest, "Your parameters (#{params.inspect}) were missing #{missing.join(", ")}"
args = arguments.map do |arg, default|
p = params.key?(arg.to_sym)
unless p || (defaults && defaults.include?(arg))
missing = arguments.reject {|arg| params.key?(arg[0].to_sym || arg[1])}
raise BadRequest, "Your parameters (#{params.inspect}) were missing #{missing.join(", ")}"
end
p ? params[arg.to_sym] : default
end
old_send_action(action, *args)
end
p ? params[arg.to_sym] : default
end
__send__(action, *args)
end

end

AbstractController::Base.send(:include, ActionArgs)
Expand Up @@ -9,14 +9,14 @@ def funky_inherited_method(foo, bar)
end

module Awesome
class ActionArgs < ActionController::Base
class ActionArgsController < ActionController::Base
def index(foo)
render :text => foo.to_s
end
end
end

class ActionArgs < ActionController::Base
class ActionArgsController < ActionController::Base
include ExtraActions

def nada
Expand Down
26 changes: 13 additions & 13 deletions spec/rails_action_args_spec.rb
Expand Up @@ -2,56 +2,56 @@

describe "RailsActionArgs" do
it "should be able to handle a nested class" do
Awesome::ActionArgs.action(:index).call(Rack::MockRequest.env_for("/?foo=bar"))[2].body.should == "bar"
Awesome::ActionArgsController.action(:index).call(Rack::MockRequest.env_for("/?foo=bar"))[2].body.should == "bar"
end

it "should be able to handle no arguments" do
ActionArgs.action(:nada).call(Rack::MockRequest.env_for("/"))[2].body.should == "NADA"
ActionArgsController.action(:nada).call(Rack::MockRequest.env_for("/"))[2].body.should == "NADA"
end

it "should be able to accept Action Arguments" do
ActionArgs.action(:index).call(Rack::MockRequest.env_for("/?foo=bar"))[2].body.should == "bar"
ActionArgsController.action(:index).call(Rack::MockRequest.env_for("/?foo=bar"))[2].body.should == "bar"
end

it "should be able to accept multiple Action Arguments" do
ActionArgs.action(:multi).call(Rack::MockRequest.env_for("/?foo=bar&bar=baz"))[2].body.should == "bar baz"
ActionArgsController.action(:multi).call(Rack::MockRequest.env_for("/?foo=bar&bar=baz"))[2].body.should == "bar baz"
end

it "should be able to handle defaults in Action Arguments" do
ActionArgs.action(:defaults).call(Rack::MockRequest.env_for("/?foo=bar"))[2].body.should == "bar bar"
ActionArgsController.action(:defaults).call(Rack::MockRequest.env_for("/?foo=bar"))[2].body.should == "bar bar"
end

it "should be able to handle out of order defaults" do
ActionArgs.action(:defaults_mixed).call(Rack::MockRequest.env_for("/?foo=bar&baz=bar"))[2].body.should == "bar bar bar"
ActionArgsController.action(:defaults_mixed).call(Rack::MockRequest.env_for("/?foo=bar&baz=bar"))[2].body.should == "bar bar bar"
end

# it "should throw a BadRequest if the arguments are not provided" do
# lambda { ActionArgs.action(:index).call(Rack::MockRequest.env_for("/")) }.should raise_error(Merb::ControllerExceptions::BadRequest)
# lambda { ActionArgsController.action(:index).call(Rack::MockRequest.env_for("/")) }.should raise_error(Merb::ControllerExceptions::BadRequest)
# end

it "should treat define_method actions as equal" do
ActionArgs.action(:dynamic_define_method).call(Rack::MockRequest.env_for("/"))[2].body.should == "mos def"
ActionArgsController.action(:dynamic_define_method).call(Rack::MockRequest.env_for("/"))[2].body.should == "mos def"
end

it "should be able to inherit actions for use with Action Arguments" do
ActionArgs.action(:funky_inherited_method).call(Rack::MockRequest.env_for("/?foo=bar&bar=baz"))[2].body.should == "bar baz"
ActionArgsController.action(:funky_inherited_method).call(Rack::MockRequest.env_for("/?foo=bar&bar=baz"))[2].body.should == "bar baz"
end

it "should be able to handle nil defaults" do
ActionArgs.action(:with_default_nil).call(Rack::MockRequest.env_for("/?foo=bar"))[2].body.should == "bar "
ActionArgsController.action(:with_default_nil).call(Rack::MockRequest.env_for("/?foo=bar"))[2].body.should == "bar "
end

it "should be able to handle [] defaults" do
ActionArgs.action(:with_default_array).call(Rack::MockRequest.env_for("/?foo=bar"))[2].body.should == "bar []"
ActionArgsController.action(:with_default_array).call(Rack::MockRequest.env_for("/?foo=bar"))[2].body.should == "bar []"
end

# it "should print out the missing parameters if all are required" do
# lambda { ActionArgs.action(:multi).call(Rack::MockRequest.env_for("/")) }.should raise_error(
# lambda { ActionArgsController.action(:multi).call(Rack::MockRequest.env_for("/")) }.should raise_error(
# Merb::ControllerExceptions::BadRequest, /were missing foo, bar/)
# end
#
# it "should only print out missing parameters" do
# lambda { ActionArgs.action(:multi).call(Rack::MockRequest.env_for("/?foo=Hello")) }.should raise_error(
# lambda { ActionArgsController.action(:multi).call(Rack::MockRequest.env_for("/?foo=Hello")) }.should raise_error(
# Merb::ControllerExceptions::BadRequest, /were missing bar/)
# end
end
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Expand Up @@ -5,7 +5,7 @@
require 'action_controller'
require 'rails_action_args'
require 'spec'
require File.expand_path(File.join(File.dirname(__FILE__), "controllers", "action_args"))
require File.expand_path(File.join(File.dirname(__FILE__), "controllers", "action_args_controller"))

Spec::Runner.configure do |config|
end

0 comments on commit 2e6efcc

Please sign in to comment.