params_ready_rails5 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/lib/arel/cte_name.rb +20 -0
  3. data/lib/params_ready/builder.rb +161 -0
  4. data/lib/params_ready/error.rb +31 -0
  5. data/lib/params_ready/extensions/class_reader_writer.rb +33 -0
  6. data/lib/params_ready/extensions/collection.rb +43 -0
  7. data/lib/params_ready/extensions/delegation.rb +25 -0
  8. data/lib/params_ready/extensions/finalizer.rb +26 -0
  9. data/lib/params_ready/extensions/freezer.rb +49 -0
  10. data/lib/params_ready/extensions/hash.rb +46 -0
  11. data/lib/params_ready/extensions/late_init.rb +38 -0
  12. data/lib/params_ready/extensions/registry.rb +44 -0
  13. data/lib/params_ready/extensions/undefined.rb +23 -0
  14. data/lib/params_ready/format.rb +132 -0
  15. data/lib/params_ready/helpers/arel_builder.rb +68 -0
  16. data/lib/params_ready/helpers/callable.rb +14 -0
  17. data/lib/params_ready/helpers/conditional_block.rb +31 -0
  18. data/lib/params_ready/helpers/find_in_hash.rb +22 -0
  19. data/lib/params_ready/helpers/interface_definer.rb +48 -0
  20. data/lib/params_ready/helpers/key_map.rb +176 -0
  21. data/lib/params_ready/helpers/memo.rb +41 -0
  22. data/lib/params_ready/helpers/options.rb +107 -0
  23. data/lib/params_ready/helpers/parameter_definer_class_methods.rb +39 -0
  24. data/lib/params_ready/helpers/parameter_storage_class_methods.rb +63 -0
  25. data/lib/params_ready/helpers/parameter_user_class_methods.rb +35 -0
  26. data/lib/params_ready/helpers/relation_builder_wrapper.rb +35 -0
  27. data/lib/params_ready/helpers/rule.rb +76 -0
  28. data/lib/params_ready/helpers/storage.rb +30 -0
  29. data/lib/params_ready/helpers/usage_rule.rb +36 -0
  30. data/lib/params_ready/input_context.rb +31 -0
  31. data/lib/params_ready/intent.rb +70 -0
  32. data/lib/params_ready/marshaller/array_marshallers.rb +132 -0
  33. data/lib/params_ready/marshaller/builder_module.rb +9 -0
  34. data/lib/params_ready/marshaller/collection.rb +165 -0
  35. data/lib/params_ready/marshaller/definition_module.rb +63 -0
  36. data/lib/params_ready/marshaller/enum_set_marshallers.rb +96 -0
  37. data/lib/params_ready/marshaller/parameter_module.rb +11 -0
  38. data/lib/params_ready/marshaller/polymorph_marshallers.rb +67 -0
  39. data/lib/params_ready/marshaller/struct_marshallers.rb +100 -0
  40. data/lib/params_ready/marshaller/tuple_marshallers.rb +103 -0
  41. data/lib/params_ready/ordering/column.rb +60 -0
  42. data/lib/params_ready/ordering/ordering.rb +276 -0
  43. data/lib/params_ready/output_parameters.rb +138 -0
  44. data/lib/params_ready/pagination/abstract_pagination.rb +18 -0
  45. data/lib/params_ready/pagination/cursor.rb +171 -0
  46. data/lib/params_ready/pagination/direction.rb +148 -0
  47. data/lib/params_ready/pagination/keyset_pagination.rb +254 -0
  48. data/lib/params_ready/pagination/keysets.rb +70 -0
  49. data/lib/params_ready/pagination/nulls.rb +31 -0
  50. data/lib/params_ready/pagination/offset_pagination.rb +130 -0
  51. data/lib/params_ready/pagination/tendency.rb +28 -0
  52. data/lib/params_ready/parameter/abstract_struct_parameter.rb +204 -0
  53. data/lib/params_ready/parameter/array_parameter.rb +197 -0
  54. data/lib/params_ready/parameter/definition.rb +272 -0
  55. data/lib/params_ready/parameter/enum_set_parameter.rb +102 -0
  56. data/lib/params_ready/parameter/parameter.rb +475 -0
  57. data/lib/params_ready/parameter/polymorph_parameter.rb +172 -0
  58. data/lib/params_ready/parameter/state.rb +132 -0
  59. data/lib/params_ready/parameter/struct_parameter.rb +64 -0
  60. data/lib/params_ready/parameter/tuple_parameter.rb +152 -0
  61. data/lib/params_ready/parameter/value_parameter.rb +186 -0
  62. data/lib/params_ready/parameter_definer.rb +14 -0
  63. data/lib/params_ready/parameter_user.rb +35 -0
  64. data/lib/params_ready/query/array_grouping.rb +68 -0
  65. data/lib/params_ready/query/custom_predicate.rb +102 -0
  66. data/lib/params_ready/query/exists_predicate.rb +103 -0
  67. data/lib/params_ready/query/fixed_operator_predicate.rb +77 -0
  68. data/lib/params_ready/query/grouping.rb +177 -0
  69. data/lib/params_ready/query/join_clause.rb +87 -0
  70. data/lib/params_ready/query/nullness_predicate.rb +71 -0
  71. data/lib/params_ready/query/polymorph_predicate.rb +77 -0
  72. data/lib/params_ready/query/predicate.rb +203 -0
  73. data/lib/params_ready/query/predicate_operator.rb +132 -0
  74. data/lib/params_ready/query/relation.rb +337 -0
  75. data/lib/params_ready/query/structured_grouping.rb +58 -0
  76. data/lib/params_ready/query/variable_operator_predicate.rb +125 -0
  77. data/lib/params_ready/query_context.rb +21 -0
  78. data/lib/params_ready/restriction.rb +252 -0
  79. data/lib/params_ready/result.rb +109 -0
  80. data/lib/params_ready/value/coder.rb +210 -0
  81. data/lib/params_ready/value/constraint.rb +198 -0
  82. data/lib/params_ready/value/custom.rb +56 -0
  83. data/lib/params_ready/value/validator.rb +81 -0
  84. data/lib/params_ready/version.rb +7 -0
  85. data/lib/params_ready.rb +28 -0
  86. metadata +227 -0
@@ -0,0 +1,68 @@
1
+ require_relative '../error'
2
+
3
+ module ParamsReady
4
+ module Helpers
5
+ class ArelBuilder
6
+ def self.instance(object, arel_table: nil)
7
+ case object
8
+ when Arel::Nodes::Node, Arel::Nodes::SqlLiteral, Arel::Attribute
9
+ raise ParamsReadyError, "Arel table unexpected" unless arel_table.nil? || arel_table == :none
10
+ ArelObject.new(object)
11
+ when Proc
12
+ raise ParamsReadyError, "Arel table unexpected" unless arel_table.nil? || arel_table == :none
13
+ Callable.new(object)
14
+ when String, Symbol
15
+ Literal.new(object, arel_table)
16
+ else
17
+ raise ParamsReadyError, "Unexpected type for arel builder: #{object.class.name}"
18
+ end
19
+ end
20
+
21
+ def self.safe_name(name)
22
+ name[0...64]
23
+ end
24
+
25
+ class Callable
26
+ def initialize(proc)
27
+ @proc = proc
28
+ end
29
+
30
+ def to_arel(*args)
31
+ result = @proc.call(*args)
32
+ case result
33
+ when String, Symbol
34
+ Helpers::ArelBuilder.instance(result).to_arel(*args)
35
+ else
36
+ result
37
+ end
38
+ end
39
+ end
40
+
41
+ class Literal
42
+ def initialize(literal, arel_table)
43
+ @literal = literal.to_s
44
+ @arel_table = arel_table
45
+ end
46
+
47
+ def to_arel(default_table, _, _)
48
+ arel_table = @arel_table || default_table
49
+ if arel_table == :none
50
+ Arel::Nodes::SqlLiteral.new(@literal)
51
+ else
52
+ arel_table[@literal]
53
+ end
54
+ end
55
+ end
56
+
57
+ class ArelObject
58
+ def initialize(node)
59
+ @node = node
60
+ end
61
+
62
+ def to_arel(_, _, _)
63
+ @node
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,14 @@
1
+ module ParamsReady
2
+ module Helpers
3
+ class Callable
4
+ def initialize(&block)
5
+ @block = block
6
+ freeze
7
+ end
8
+
9
+ def call
10
+ @block.call
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'rule'
2
+ require_relative '../error'
3
+
4
+ module ParamsReady
5
+ module Helpers
6
+ class Conditional
7
+ def initialize(rule: nil)
8
+ @rule = Helpers::Rule(rule)
9
+ freeze
10
+ end
11
+
12
+ def perform?(general_rule, name)
13
+ if @rule.nil?
14
+ general_rule
15
+ else
16
+ @rule.include?(name)
17
+ end
18
+ end
19
+ end
20
+
21
+ class ConditionalBlock < Conditional
22
+ attr_reader :block
23
+
24
+ def initialize(rule: nil, &block)
25
+ raise ParamsReadyError, "Block must not be empty" if block.nil?
26
+ @block = block
27
+ super(rule: rule)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../extensions/undefined'
2
+ require_relative 'key_map'
3
+
4
+ module ParamsReady
5
+ module Helpers
6
+ module FindInHash
7
+ def self.find_in_hash(hash, name_or_path)
8
+ return false, Extensions::Undefined if hash.nil?
9
+
10
+ found = if name_or_path.is_a? Array
11
+ *path, name = name_or_path
12
+ Helpers::KeyMap::Mapping::Path.dig(name, hash, path)
13
+ else
14
+ Extensions::Hash.indifferent_access(hash, name_or_path, Extensions::Undefined)
15
+ end
16
+
17
+ return false, Extensions::Undefined if found == Extensions::Undefined
18
+ return true, found
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,48 @@
1
+ module ParamsReady
2
+ module Helpers
3
+ class InterfaceDefiner
4
+ def initialize(action_names, user)
5
+ @action_names = action_names
6
+ @user = user
7
+ end
8
+
9
+ def parameters(*names)
10
+ names.each do |name|
11
+ parameter(name)
12
+ end
13
+ end
14
+
15
+ def relations(*names)
16
+ names.each do |name|
17
+ relation(name)
18
+ end
19
+ end
20
+
21
+ def parameter(name)
22
+ @user.use_parameter(name, only: @action_names)
23
+ end
24
+
25
+ def relation(name)
26
+ @user.use_relation(name, only: @action_names)
27
+ end
28
+
29
+ def define(parameter: nil, relation: nil, parameters: [], relations: [], &block)
30
+ parameters = self.class.complete_list(parameter, parameters)
31
+ parameters(*parameters)
32
+ relations = self.class.complete_list(relation, relations)
33
+ relations(*relations)
34
+ instance_eval(&block) unless block.nil?
35
+ @option
36
+ end
37
+
38
+ def self.complete_list(singular, plural)
39
+ list = singular.nil? ? plural : [singular, *plural]
40
+ normalize_list(list)
41
+ end
42
+
43
+ def self.normalize_list(list)
44
+ list.map(&:to_sym)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,176 @@
1
+ require_relative '../error'
2
+ require_relative '../extensions/undefined'
3
+ require_relative '../extensions/hash'
4
+
5
+ module ParamsReady
6
+ module Helpers
7
+ class KeyMap
8
+ class Mapping
9
+ class Path
10
+ attr_reader :path, :names
11
+
12
+ def initialize(path, names = [])
13
+ @path = path.map(&:to_sym).freeze
14
+ @names = names
15
+ end
16
+
17
+ def add_names(names)
18
+ names.each{ |name| add_name(name) }
19
+ end
20
+
21
+ def add_name(name)
22
+ @names << name
23
+ end
24
+
25
+ def dig(name, hash)
26
+ self.class.dig(name, hash, @path)
27
+ end
28
+
29
+ def self.dig(name, hash, path)
30
+ result = path.reduce(hash) do |current, name|
31
+ next unless Extensions::Hash.acts_as_hash?(current)
32
+
33
+ Extensions::Hash.indifferent_access current, name, nil
34
+ end
35
+
36
+ return Extensions::Undefined unless Extensions::Hash.acts_as_hash?(result)
37
+
38
+ Extensions::Hash.indifferent_access result, name, Extensions::Undefined
39
+ end
40
+
41
+ def store(name, value, hash)
42
+ self.class.store(name, value, hash, @path)
43
+ end
44
+
45
+ def self.store(name, value, hash, path)
46
+ return if value == Extensions::Undefined
47
+
48
+ result = path.reduce(hash) do |current, name|
49
+ current[name] ||= {}
50
+ current[name]
51
+ end
52
+
53
+ result[name] = value
54
+ result
55
+ end
56
+
57
+ def =~(other)
58
+ raise ParamsReadyError, "Can't match path with #{other.class.name}" unless other.is_a? Path
59
+ path == other.path
60
+ end
61
+
62
+ def ==(other)
63
+ raise ParamsReadyError, "Can't compare path with #{other.class.name}" unless other.is_a? Path
64
+ path == other.path && names == other.names
65
+ end
66
+ end
67
+
68
+ def initialize(alt_path, alt_names, std_path, std_names)
69
+ if alt_names.length != std_names.length
70
+ msg = "Expected equal number of alternative and standard names, got #{alt_names.length}/#{std_names.length}"
71
+ raise ParamsReadyError, msg
72
+ end
73
+
74
+ @alt = Path.new(alt_path, alt_names)
75
+ @std = Path.new(std_path, std_names)
76
+ end
77
+
78
+ def add_names(altn, stdn)
79
+ @alt.add_name altn
80
+ @std.add_name stdn
81
+ end
82
+
83
+ def remap(from, to, input, target)
84
+ path(from).names.each_with_index do |input_name, idx|
85
+ value = dig(from, input_name, input)
86
+ target_name = path(to).names[idx]
87
+ store(to, target_name, value, target)
88
+ end
89
+ end
90
+
91
+ def merge!(other)
92
+ raise ParamsReadyError, "Can't merge non_matching mapping" unless self =~ other
93
+
94
+ @alt.add_names(other.alt.names)
95
+ @std.add_names(other.std.names)
96
+ end
97
+
98
+ def dig(schema, name, hash)
99
+ path(schema).dig(name, hash)
100
+ end
101
+
102
+ def store(schema, name, value, hash)
103
+ path(schema).store(name, value, hash)
104
+ end
105
+
106
+ def path(schema)
107
+ case schema
108
+ when :alt then @alt
109
+ when :std then @std
110
+ else
111
+ raise ParamsReadyError, "Unexpected naming schema: #{schema}"
112
+ end
113
+ end
114
+
115
+ def =~(other)
116
+ raise ParamsReadyError, "Can't match path with #{other.class.name}" unless other.is_a? Mapping
117
+ return false unless path(:alt) =~ other.path(:alt)
118
+ return false unless path(:std) =~ other.path(:std)
119
+
120
+ true
121
+ end
122
+
123
+ protected
124
+ attr_reader :alt, :std
125
+ end
126
+
127
+ def initialize
128
+ @mappings = []
129
+ end
130
+
131
+ def map(from, to:)
132
+ alt_path, alt_names = self.class.split_map(from)
133
+ std_path, std_names = self.class.split_map(to)
134
+ mapping = Mapping.new(alt_path, alt_names, std_path, std_names)
135
+ merge_or_add_mapping(mapping)
136
+ self
137
+ end
138
+
139
+ def merge_or_add_mapping(mapping)
140
+ if (existing = @mappings.find { |candidate| candidate =~ mapping })
141
+ existing.merge!(mapping)
142
+ else
143
+ @mappings << mapping
144
+ end
145
+ mapping
146
+ end
147
+
148
+ def to_standard(hash)
149
+ remap(:alt, :std, hash)
150
+ end
151
+
152
+ def to_alternative(hash)
153
+ remap(:std, :alt, hash)
154
+ end
155
+
156
+ def remap(from, to, input)
157
+ @mappings.each_with_object({}) do |mapping, result|
158
+ mapping.remap(from, to, input, result)
159
+ end
160
+ end
161
+
162
+ def freeze
163
+ @mappings.each(&:freeze)
164
+ super
165
+ end
166
+
167
+ def self.split_map(array)
168
+ raise ParamsReadyError, "Array expected, got: #{array.class.name}" unless array.is_a? Array
169
+ names = array.last || []
170
+ raise ParamsReadyError, "Array expected, got: #{names.class.name}" unless names.is_a? Array
171
+ paths = array[0...-1]
172
+ [paths, names]
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,41 @@
1
+ require_relative '../extensions/undefined'
2
+ require_relative '../extensions/hash'
3
+
4
+
5
+
6
+ module ParamsReady
7
+ module Helpers
8
+ class Memo
9
+ def initialize(slots = 1)
10
+ raise ParamsReadyError, "Expected positive value for number of slots, got: '#{slots}'" unless slots > 0
11
+ @slots = slots
12
+ @cache = nil
13
+ end
14
+
15
+ def cached_value(key)
16
+ cache = @cache
17
+ return Extensions::Undefined if cache.nil?
18
+ return Extensions::Undefined unless cache.key? key
19
+
20
+ cache[key]
21
+ end
22
+
23
+ def cache_value(value, key)
24
+ stale = @cache
25
+ return if stale&.key? key
26
+
27
+ frozen = Extensions::Hash.try_deep_freeze(value)
28
+
29
+ fresh = if stale.nil? || @slots == 1
30
+ { key => frozen }
31
+ else
32
+ kept = stale.to_a.last(@slots - 1)
33
+
34
+ [*kept, [key, frozen]].to_h
35
+ end
36
+
37
+ @cache = fresh.freeze
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,107 @@
1
+ require_relative 'storage'
2
+ require_relative 'usage_rule'
3
+
4
+ module ParamsReady
5
+ module Helpers
6
+ class Options
7
+ attr_reader :parameters, :relations
8
+
9
+ def initialize
10
+ @parameter_rules = Hash.new
11
+ @relation_rules = Hash.new
12
+ @memo = { definitions: {} }
13
+ end
14
+
15
+ def reset_memo!(*args)
16
+ args.each do |key|
17
+ @memo[key].clear
18
+ end
19
+ end
20
+
21
+ def dup
22
+ duplicate = Options.new
23
+ @parameter_rules.each do |_, rule|
24
+ duplicate.merge_parameter_rule(rule)
25
+ end
26
+ @relation_rules.each do |_, rule|
27
+ duplicate.merge_relation_rule(rule)
28
+ end
29
+ duplicate
30
+ end
31
+
32
+ def relation_definitions_for(name)
33
+ definitions_for(name, relation_rules)
34
+ end
35
+
36
+ def parameter_definitions_for(name)
37
+ definitions_for(name, parameter_rules)
38
+ end
39
+
40
+ def definitions_for(name, rules)
41
+ rules.each_with_object([]) do |(_, rule), result|
42
+ next unless rule.valid_for?(name)
43
+
44
+ result << rule.parameter_definition
45
+ end
46
+ end
47
+
48
+ def use_parameter(param, rule_args = :all)
49
+ rule = UsageRule.new(param, rule_args)
50
+ merge_parameter_rule(rule)
51
+ end
52
+
53
+ def merge_parameter_rule(rule)
54
+ reset_memo!(:definitions)
55
+ @parameter_rules = self.class.merge_rule(rule, @parameter_rules)
56
+ end
57
+
58
+ def use_relation(relation, rule_args = :all)
59
+ rule = UsageRule.new(relation, rule_args)
60
+ merge_relation_rule(rule)
61
+ end
62
+
63
+ def merge_relation_rule(rule)
64
+ reset_memo!(:definitions)
65
+ @relation_rules = self.class.merge_rule(rule, @relation_rules)
66
+ end
67
+
68
+ def parameter_rules
69
+ if block_given?
70
+ @parameter_rules.each_value do |rule|
71
+ yield rule
72
+ end
73
+ end
74
+ @parameter_rules
75
+ end
76
+
77
+ def relation_rules
78
+ if block_given?
79
+ @relation_rules.each_value do |rule|
80
+ yield rule
81
+ end
82
+ end
83
+ @relation_rules
84
+ end
85
+
86
+ def create_state_for(key)
87
+ @memo[:definitions][key] ||= begin
88
+ builder = Parameter::StateBuilder.instance
89
+ parameter_definitions_for(key).each do |definition|
90
+ builder.add definition
91
+ end
92
+ relation_definitions_for(key).each do |definition|
93
+ builder.relation definition
94
+ end
95
+ builder.build
96
+ end
97
+ end
98
+
99
+ def self.merge_rule(rule, rules)
100
+ existing = rules[rule.name]
101
+ merged = rule.merge(existing)
102
+ rules[rule.name] = merged
103
+ rules
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,39 @@
1
+ require_relative 'relation_builder_wrapper'
2
+ require_relative '../builder'
3
+
4
+ module ParamsReady
5
+ module Helpers
6
+ module ParameterDefinerClassMethods
7
+ def define_relation(*args, **opts, &block)
8
+ wrapper = ParamsReady::Helpers::RelationBuilderWrapper.new self, *args, **opts
9
+ wrapper.instance_eval(&block) unless block.nil?
10
+ relation = wrapper.build
11
+ params_ready_storage.add_relation relation
12
+ end
13
+
14
+ def define_parameter(type, *args, **opts, &block)
15
+ full_name = "define_#{type}"
16
+ parameter = Builder.send(full_name, *args, **opts, &block)
17
+ params_ready_storage.add_parameter parameter
18
+ end
19
+
20
+ def all_relations
21
+ relations = if superclass.respond_to? :all_relations
22
+ superclass.all_relations
23
+ else
24
+ {}
25
+ end
26
+ relations.merge(params_ready_storage.relations)
27
+ end
28
+
29
+ def all_parameters
30
+ parameters = if superclass.respond_to? :all_parameters
31
+ superclass.all_parameters
32
+ else
33
+ {}
34
+ end
35
+ parameters.merge(params_ready_storage.parameters)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,63 @@
1
+ require_relative 'storage'
2
+ require_relative '../error'
3
+ require_relative 'rule'
4
+
5
+ module ParamsReady
6
+ module Helpers
7
+ module ParameterStorageClassMethods
8
+ def params_ready_storage
9
+ @params_ready_storage ||= Storage.new
10
+ end
11
+
12
+ def relation_definition(key)
13
+ relations = params_ready_storage.relations
14
+ sym_key = key.to_sym
15
+ if relations.key?(sym_key)
16
+ relations[sym_key]
17
+ elsif superclass.respond_to? :relation_definition
18
+ superclass.relation_definition sym_key
19
+ else
20
+ raise ParamsReadyError, "Unknown relation '#{sym_key}'"
21
+ end
22
+ end
23
+
24
+ def parameter_definition(key)
25
+ parameters = params_ready_storage.parameters
26
+ sym_key = key.to_sym
27
+ if parameters.key? sym_key
28
+ parameters[sym_key]
29
+ elsif superclass.respond_to? :parameter_definition
30
+ superclass.parameter_definition sym_key
31
+ else
32
+ raise ParamsReadyError, "Unknown parameter '#{sym_key}'"
33
+ end
34
+ end
35
+
36
+ def include_parameters(parameter_definer, rule = nil)
37
+ rule = Helpers::Rule(rule)
38
+ parameter_definer.all_parameters.each do |key, definition|
39
+ next if rule && !rule.include?(key)
40
+
41
+ add_parameter(definition)
42
+ end
43
+ end
44
+
45
+ def add_parameter(definition)
46
+ params_ready_storage.add_parameter(definition)
47
+ end
48
+
49
+ def include_relations(parameter_definer, rule = nil)
50
+ rule = Helpers::Rule(rule)
51
+ parameter_definer.all_relations.each do |key, definition|
52
+ next if rule && !rule.include?(key)
53
+
54
+ add_relation(definition)
55
+ end
56
+ end
57
+
58
+ def add_relation(definition)
59
+ params_ready_storage.add_relation(definition)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'interface_definer'
2
+
3
+ module ParamsReady
4
+ module Helpers
5
+ module ParameterUserClassMethods
6
+ def params_ready_option
7
+ @params_ready_option ||= begin
8
+ if superclass.respond_to? :params_ready_option
9
+ # This works on assumption that superclass
10
+ # definition doesn't change during execution
11
+ superclass.params_ready_option.dup
12
+ else
13
+ ParamsReady::Helpers::Options.new
14
+ end
15
+ end
16
+ end
17
+
18
+ def use_parameter(name, rule = :all)
19
+ parameter = parameter_definition name
20
+ params_ready_option.use_parameter parameter, rule
21
+ end
22
+
23
+ def use_relation(name, rule = :all)
24
+ relation = relation_definition name
25
+ params_ready_option.use_relation relation, rule
26
+ end
27
+
28
+ def action_interface(*action_names, **opts, &block)
29
+ definer = InterfaceDefiner.new(action_names, self)
30
+
31
+ definer.define(**opts, &block)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ require_relative '../query/relation'
2
+
3
+ module ParamsReady
4
+ module Helpers
5
+ class RelationBuilderWrapper
6
+ def initialize(cache, *args, **opts)
7
+ @cache = cache
8
+ @builder = Query::RelationParameterBuilder.instance *args, **opts
9
+ end
10
+
11
+ def capture(*names)
12
+ names.each do |name|
13
+ definition = @cache.parameter_definition(name)
14
+ @builder.add definition
15
+ end
16
+ end
17
+
18
+ ruby2_keywords def method_missing(name, *args, &block)
19
+ if @builder.respond_to? name
20
+ @builder.send name, *args, &block
21
+ else
22
+ super
23
+ end
24
+ end
25
+
26
+ def respond_to_missing?(name, include_private = false)
27
+ if @builder.respond_to? name
28
+ true
29
+ else
30
+ super
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end