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
|
# File 'lib/sinja/resource.rb', line 24
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 - [*allow_opts]).empty?
resource_config[action].each do |k, v|
v.replace([*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 = {
:create=>2,
:index=>-1,
:fetch=>-1,
:show_many=>-1
}.freeze[action] || 1
define_method(action) do |*args|
raise ArgumentError, "Unexpected argument(s) for `#{action}' action helper" \
unless args.length == block.arity
public_send("before_#{action}", *args) \
if respond_to?("before_#{action}")
case result = instance_exec(*args, &block)
when Array
opts = {}
if Hash === result.last
opts = result.pop
elsif required_arity < 0 && !(Array === result.first)
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
|