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/sinja/resource.rb', line 31
def def_action_helper(context, action, allow_opts=[])
abort "Action helper names can't overlap with Sinatra DSL" \
if Sinatra::Base.respond_to?(action)
context.define_singleton_method(action) do |**opts, &block|
abort "Unexpected option(s) for `#{action}' action helper" \
unless (opts.keys - Array(allow_opts)).empty?
resource_config[action].each do |k, v|
v.replace(Array(opts[k])) if opts.key?(k)
end
return unless block ||=
case !method_defined?(action) && action
when :show
proc { resource } if method_defined?(:find)
end
required_arity = ARITIES[action]
define_method(action) do |*args|
raise ArgumentError, "Unexpected argument(s) for `#{action}' action helper" \
unless args.length == block.arity
public_send("before_#{action}", *args.take(method("before_#{action}").arity.abs)) \
if respond_to?("before_#{action}")
case result = instance_exec(*args, &block)
when Array
opts = {}
if result.last.instance_of?(Hash)
opts = result.pop
elsif required_arity < 0 && !result.first.is_a?(Array)
result = [result]
end
raise ActionHelperError, "Unexpected return value(s) from `#{action}' action helper" \
unless result.length == required_arity.abs
result.push(opts)
when Hash
Array.new(required_arity.abs).push(result)
else
[result, nil].take(required_arity.abs).push({})
end
end
define_singleton_method("remove_#{action}") do
remove_method(action) if respond_to?(action)
end
end
end
|