Class: Praxis::Extensions::Pagination::OrderingParams
- Inherits:
-
Object
- Object
- Praxis::Extensions::Pagination::OrderingParams
- Extended by:
- Forwardable
- Includes:
- Attributor::Dumpable, Attributor::Type
- Defined in:
- lib/praxis/extensions/pagination/ordering_params.rb
Defined Under Namespace
Classes: DSLCompiler
Class Attribute Summary collapse
-
.enforce_all ⇒ Object
True when we need to enforce the allowed fields at all ordering positions.
-
.fields_allowed ⇒ Object
True when we need to enforce the allowed fields at all ordering positions.
-
.media_type ⇒ Object
readonly
Returns the value of attribute media_type.
Instance Attribute Summary collapse
-
#items ⇒ Object
readonly
Returns the value of attribute items.
Class Method Summary collapse
- .construct(pagination_definition, **options) ⇒ Object
- .constructable? ⇒ Boolean
- .describe(_root = false, example: nil) ⇒ Object
- .display_name ⇒ Object
- .dump(value, **_opts) ⇒ Object
- .enforce_all_fields(newval = nil) ⇒ Object
- .example(_context = Attributor::DEFAULT_ROOT_CONTEXT, **_options) ⇒ Object
- .family ⇒ Object
- .for(media_type, **_opts) ⇒ Object
- .json_schema_type ⇒ Object
- .load(order, _context = Attributor::DEFAULT_ROOT_CONTEXT, **_options) ⇒ Object
- .name ⇒ Object
- .native_type ⇒ Object
- .validate(value, context = Attributor::DEFAULT_ROOT_CONTEXT, _attribute = nil) ⇒ Object
Instance Method Summary collapse
- #dump ⇒ Object
- #each(&block) ⇒ Object
-
#initialize(parsed) ⇒ OrderingParams
constructor
A new instance of OrderingParams.
-
#valid_attribute_path?(media_type, path) ⇒ Boolean
Looks up if the given path (with symbol attribute names at each component) is actually a valid path from the given mediatype.
- #validate(_context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
Constructor Details
#initialize(parsed) ⇒ OrderingParams
Returns a new instance of OrderingParams.
195 196 197 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 195 def initialize(parsed) @items = parsed end |
Class Attribute Details
.enforce_all ⇒ Object
True when we need to enforce the allowed fields at all ordering positions
84 85 86 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 84 def enforce_all @enforce_all end |
.fields_allowed ⇒ Object
True when we need to enforce the allowed fields at all ordering positions
84 85 86 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 84 def fields_allowed @fields_allowed end |
.media_type ⇒ Object (readonly)
Returns the value of attribute media_type.
83 84 85 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 83 def media_type @media_type end |
Instance Attribute Details
#items ⇒ Object (readonly)
Returns the value of attribute items.
100 101 102 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 100 def items @items end |
Class Method Details
.construct(pagination_definition, **options) ⇒ Object
126 127 128 129 130 131 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 126 def self.construct(pagination_definition, **) return self if pagination_definition.nil? DSLCompiler.new(self, **).parse(*pagination_definition) self end |
.constructable? ⇒ Boolean
122 123 124 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 122 def self.constructable? true end |
.describe(_root = false, example: nil) ⇒ Object
184 185 186 187 188 189 190 191 192 193 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 184 def self.describe(_root = false, example: nil) hash = super if fields_allowed hash[:fields_allowed] = fields_allowed hash[:enforced_for] = enforce_all ? :all : :first end hash end |
.display_name ⇒ Object
114 115 116 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 114 def self.display_name 'Ordering' end |
.dump(value, **_opts) ⇒ Object
180 181 182 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 180 def self.dump(value, **_opts) load(value).dump end |
.enforce_all_fields(newval = nil) ⇒ Object
66 67 68 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 66 def self.enforce_all_fields(newval = nil) newval ? @enforce_all_fields = newval : @enforce_all_fields end |
.example(_context = Attributor::DEFAULT_ROOT_CONTEXT, **_options) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 133 def self.example(_context = Attributor::DEFAULT_ROOT_CONTEXT, **) fields = if media_type chosen_set = if enforce_all fields_allowed.sample(2) else starting_set = fields_allowed.sample(1) simple_attrs = media_type.attributes.select do |_k, attr| attr.type == Attributor::String || attr.type < Attributor::Numeric || attr.type < Attributor::Temporal end.keys starting_set + simple_attrs.reject { |attr| attr == starting_set.first }.sample(1) end chosen_set.each_with_object([]) do |chosen, arr| sign = rand(10) < 5 ? '-' : '' arr << "#{sign}#{chosen}" end.join(',') else 'name,last_name,-birth_date' end load(fields) end |
.family ⇒ Object
118 119 120 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 118 def self.family 'string' end |
.for(media_type, **_opts) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 86 def for(media_type, **_opts) unless media_type < Praxis::MediaType raise ArgumentError, "Invalid type: #{media_type.name} for Ordering. " \ 'Must be a subclass of MediaType' end ::Class.new(self) do @media_type = media_type # Default is to only enforce the allowed fields in the first ordering position (the one typicall uses an index if there) @enforce_all = OrderingParams.enforce_all_fields end end |
.json_schema_type ⇒ Object
102 103 104 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 102 def self.json_schema_type :string end |
.load(order, _context = Attributor::DEFAULT_ROOT_CONTEXT, **_options) ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 159 def self.load(order, _context = Attributor::DEFAULT_ROOT_CONTEXT, **) return order if order.is_a?(native_type) parsed_order = {} unless order.nil? parsed_order = order.split(',').each_with_object([]) do |order_string, arr| item = case order_string[0] when '-' { desc: order_string[1..].to_s } when '+' { asc: order_string[1..].to_s } else { asc: order_string.to_s } end arr.push item end end new(parsed_order) end |
.name ⇒ Object
110 111 112 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 110 def self.name 'Praxis::Types::OrderingParams' end |
.native_type ⇒ Object
106 107 108 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 106 def self.native_type self end |
.validate(value, context = Attributor::DEFAULT_ROOT_CONTEXT, _attribute = nil) ⇒ Object
154 155 156 157 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 154 def self.validate(value, context = Attributor::DEFAULT_ROOT_CONTEXT, _attribute = nil) instance = load(value, context) instance.validate(context) end |
Instance Method Details
#dump ⇒ Object
226 227 228 229 230 231 232 233 234 235 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 226 def dump items.each_with_object([]) do |spec, arr| dir, field = spec.first arr << if dir == :desc "-#{field}" else field end end.join(',') end |
#each(&block) ⇒ Object
237 238 239 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 237 def each(&block) items.each(&block) end |
#valid_attribute_path?(media_type, path) ⇒ Boolean
Looks up if the given path (with symbol attribute names at each component) is actually a valid path from the given mediatype
243 244 245 246 247 248 249 250 251 252 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 243 def valid_attribute_path?(media_type, path) first, *rest = path # Get the member type if this is a collection media_type = media_type.member_type if media_type.respond_to?(:member_attribute) if (attribute = media_type.attributes[first]) rest.empty? ? true : valid_attribute_path?(attribute.type, rest) else false end end |
#validate(_context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/praxis/extensions/pagination/ordering_params.rb', line 199 def validate(_context = Attributor::DEFAULT_ROOT_CONTEXT) return [] if items.blank? errors = [] if self.class.fields_allowed # Validate against the enforced components (either all, or just the first one) enforceable_items = self.class.enforce_all ? items : [items.first] enforceable_items.each do |spec| _dir, field = spec.first field = field.to_sym next if self.class.fields_allowed.include?(field) field_path = field.to_s.split('.').map(&:to_sym) errors << if valid_attribute_path?(self.class.media_type, field_path) "Ordering by field \'#{field}\' in media type #{self.class.media_type.name} is disallowed. Ordering is only allowed using the following fields: " + self.class.fields_allowed.map { |f| "\'#{f}\'" }.join(', ').to_s else "Ordering by field \'#{field}\' is not possible as this field is not reachable from " \ "media type #{self.class.media_type.name}" end end end errors end |