Class: Praxis::Extensions::Pagination::PaginationParams
- Inherits:
-
Object
- Object
- Praxis::Extensions::Pagination::PaginationParams
- Includes:
- Attributor::Dumpable, Attributor::Type
- Defined in:
- lib/praxis/extensions/pagination/pagination_params.rb
Defined Under Namespace
Classes: DSLCompiler
Constant Summary collapse
- CLAUSE_REGEX =
/(?<type>[^=]+)=(?<value>.+)$/.freeze
Class Attribute Summary collapse
-
.defaults ⇒ Object
readonly
Returns the value of attribute defaults.
-
.fields_allowed ⇒ Object
Returns the value of attribute fields_allowed.
-
.media_type ⇒ Object
readonly
Returns the value of attribute media_type.
Instance Attribute Summary collapse
-
#by ⇒ Object
readonly
Returns the value of attribute by.
-
#from ⇒ Object
readonly
Returns the value of attribute from.
-
#items ⇒ Object
readonly
Returns the value of attribute items.
-
#page ⇒ Object
readonly
Returns the value of attribute page.
-
#total_count ⇒ Object
readonly
Returns the value of attribute total_count.
Class Method Summary collapse
-
.coerce_field(name, value) ⇒ Object
Silently ignore if the fiels does not exist…let’s let the validation check it instead.
- .construct(pagination_definition, **options) ⇒ Object
- .constructable? ⇒ Boolean
- .default_page_size(newval = nil) ⇒ Object
- .describe(_root = false, example: nil) ⇒ Object
- .disallow_cursor_by_default(newval = nil) ⇒ Object
- .disallow_paging_by_default(newval = nil) ⇒ Object
- .display_name ⇒ Object
- .dump(value, **_opts) ⇒ Object
- .example(_context = Attributor::DEFAULT_ROOT_CONTEXT, **_options) ⇒ Object
- .family ⇒ Object
- .for(media_type, **_opts) ⇒ Object
- .json_schema_type ⇒ Object
- .load(paginator, _context = Attributor::DEFAULT_ROOT_CONTEXT, **_options) ⇒ Object
- .max_items(newval = nil) ⇒ Object
- .name ⇒ Object
- .native_type ⇒ Object
- .paging_default_mode(newval = nil) ⇒ Object
- .validate(value, context = Attributor::DEFAULT_ROOT_CONTEXT, _attribute = nil) ⇒ Object
Instance Method Summary collapse
-
#dump ⇒ Object
Dump back string parseable form.
-
#initialize(parsed) ⇒ PaginationParams
constructor
Instance methods.
- #validate(_context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
Constructor Details
#initialize(parsed) ⇒ PaginationParams
Instance methods
304 305 306 307 308 309 310 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 304 def initialize(parsed) @by = parsed[:by] @from = parsed[:from] @items = parsed[:items] @page = parsed[:page] @total_count = parsed[:total_count] end |
Class Attribute Details
.defaults ⇒ Object (readonly)
Returns the value of attribute defaults.
148 149 150 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 148 def defaults @defaults end |
.fields_allowed ⇒ Object
Returns the value of attribute fields_allowed.
149 150 151 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 149 def fields_allowed @fields_allowed end |
.media_type ⇒ Object (readonly)
Returns the value of attribute media_type.
148 149 150 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 148 def media_type @media_type end |
Instance Attribute Details
#by ⇒ Object (readonly)
Returns the value of attribute by.
201 202 203 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 201 def by @by end |
#from ⇒ Object (readonly)
Returns the value of attribute from.
201 202 203 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 201 def from @from end |
#items ⇒ Object (readonly)
Returns the value of attribute items.
201 202 203 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 201 def items @items end |
#page ⇒ Object (readonly)
Returns the value of attribute page.
201 202 203 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 201 def page @page end |
#total_count ⇒ Object (readonly)
Returns the value of attribute total_count.
201 202 203 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 201 def total_count @total_count end |
Class Method Details
.coerce_field(name, value) ⇒ Object
Silently ignore if the fiels does not exist…let’s let the validation check it instead
293 294 295 296 297 298 299 300 301 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 293 def self.coerce_field(name, value) if media_type&.attributes attrs = media_type&.attributes || {} attribute = attrs[name.to_sym] attribute&.type&.load(value) else value end end |
.construct(pagination_definition, **options) ⇒ Object
194 195 196 197 198 199 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 194 def self.construct(pagination_definition, **) return self if pagination_definition.nil? DSLCompiler.new(self, **).parse(*pagination_definition) self end |
.constructable? ⇒ Boolean
190 191 192 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 190 def self.constructable? true end |
.default_page_size(newval = nil) ⇒ Object
124 125 126 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 124 def self.default_page_size(newval = nil) newval ? @default_page_size = newval : @default_page_size end |
.describe(_root = false, example: nil) ⇒ Object
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 274 def self.describe(_root = false, example: nil) hash = super hash[:fields_allowed] = fields_allowed if fields_allowed if defaults hash[:max_items] = defaults[:max_items] hash[:page_size] = defaults[:page_size] hash[:default_mode] = defaults[:default_mode] disallowed = [] disallowed << :paging if defaults[:disallow_paging] == true disallowed << :cursor if defaults[:disallow_cursor] == true hash[:disallowed] = disallowed unless disallowed.empty? end hash end |
.disallow_cursor_by_default(newval = nil) ⇒ Object
132 133 134 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 132 def self.disallow_cursor_by_default(newval = nil) newval ? @disallow_cursor_by_default = newval : @disallow_cursor_by_default end |
.disallow_paging_by_default(newval = nil) ⇒ Object
128 129 130 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 128 def self.disallow_paging_by_default(newval = nil) newval ? @disallow_paging_by_default = newval : @disallow_paging_by_default end |
.display_name ⇒ Object
182 183 184 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 182 def self.display_name 'Paginator' end |
.dump(value, **_opts) ⇒ Object
270 271 272 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 270 def self.dump(value, **_opts) load(value).dump end |
.example(_context = Attributor::DEFAULT_ROOT_CONTEXT, **_options) ⇒ Object
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 203 def self.example(_context = Attributor::DEFAULT_ROOT_CONTEXT, **) fields = if media_type mt_example = media_type.example simple_attrs = media_type.attributes.select do |_k, attr| attr.type == Attributor::String || attr.type == Attributor::Integer end selectable = mt_example.object.keys & simple_attrs.keys by = selectable.sample(1).first from = media_type.attributes[by].example(parent: mt_example).to_s # Make sure to encode the value of the from, as it can contain commas and such # Only add the from parameter if it's not empty (an empty from is not allowed and it's gonna blow up in load) optional_from_component = from && !from.empty? ? ",from=#{CGI.escape(from)}" : '' "by=#{by}#{optional_from_component},items=#{defaults[:page_size]}" else 'by=id,from=20,items=100' end load(fields) end |
.family ⇒ Object
186 187 188 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 186 def self.family 'string' end |
.for(media_type, **_opts) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 151 def for(media_type, **_opts) unless media_type < Praxis::MediaType raise ArgumentError, "Invalid type: #{media_type.name} for Paginator. " \ 'Must be a subclass of MediaType' end ::Class.new(self) do @media_type = media_type @defaults = { page_size: PaginationParams.default_page_size, max_items: PaginationParams.max_items, disallow_paging: PaginationParams.disallow_paging_by_default, disallow_cursor: PaginationParams.disallow_cursor_by_default, default_mode: PaginationParams.paging_default_mode } end end |
.json_schema_type ⇒ Object
170 171 172 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 170 def self.json_schema_type :string end |
.load(paginator, _context = Attributor::DEFAULT_ROOT_CONTEXT, **_options) ⇒ Object
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 229 def self.load(paginator, _context = Attributor::DEFAULT_ROOT_CONTEXT, **) return paginator if paginator.is_a?(native_type) || paginator.nil? parsed = {} unless paginator.nil? parsed = paginator.split(',').each_with_object({}) do |paginator_string, hash| match = CLAUSE_REGEX.match(paginator_string) case match[:type].to_sym when :page hash[:page] = Integer(match[:value]) when :by hash[:by] = match[:value] when :from hash[:from] = match[:value] when :total_count hash[:total_count] = (match[:value] != 'false') # unless explicitly set to false, we'll take it as true... when :items hash[:items] = Integer(match[:value]) else raise "Error loading pagination parameters: unknown parameter with name '#{match[:type]}' found" end end end parsed[:items] = defaults[:page_size] unless parsed.key?(:items) parsed[:from] = coerce_field(parsed[:by], parsed[:from]) if parsed.key?(:from) # If no by/from or page specified, we're gonna apply the defaults unless parsed.key?(:by) || parsed.key?(:from) || parsed.key?(:page) mode, value = defaults[:default_mode].first case mode when :by parsed[:by] = value when :page parsed[:page] = value end end new(parsed) end |
.max_items(newval = nil) ⇒ Object
120 121 122 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 120 def self.max_items(newval = nil) newval ? @max_items = newval : @max_items end |
.name ⇒ Object
178 179 180 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 178 def self.name 'Extensions::Pagination::PaginationParams' end |
.native_type ⇒ Object
174 175 176 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 174 def self.native_type self end |
.paging_default_mode(newval = nil) ⇒ Object
136 137 138 139 140 141 142 143 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 136 def self.paging_default_mode(newval = nil) if newval raise 'Error setting paging_default_mode, value must be a hash with :by or :page keys' unless newval.respond_to?(:keys) && newval.keys.size == 1 && %i[by page].include?(newval.keys.first) @paging_default_mode = newval end @paging_default_mode end |
.validate(value, context = Attributor::DEFAULT_ROOT_CONTEXT, _attribute = nil) ⇒ Object
223 224 225 226 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 223 def self.validate(value, context = Attributor::DEFAULT_ROOT_CONTEXT, _attribute = nil) instance = load(value, context) instance.validate(context) end |
Instance Method Details
#dump ⇒ Object
Dump back string parseable form
339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 339 def dump str = if @page "page=#{@page}" else s = "by=#{@by}" s += ",from=#{@from}" if @from s end str += ",items=#{items}" if @items str += ',total_count=true' if @total_count str end |
#validate(_context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 312 def validate(_context = Attributor::DEFAULT_ROOT_CONTEXT) errors = [] if page errors << "Page-based pagination is disallowed (i.e., using 'page=' parameter)" if self.class.defaults[:disallow_paging] elsif self.class.defaults[:disallow_cursor] errors << "Cursor-based pagination is disallowed (i.e., using 'by=' or 'from=' parameter)" end errors << "Page parameter cannot be zero or negative! (got: #{parsed.page})" if page && page <= 0 errors << "Value of 'items' is invalid (got: #{items}). It must be positive, and smaller than the maximum amount of items per request (set to #{self.class.defaults[:max_items]})" if items && (items <= 0 || (self.class.defaults[:max_items] && items > self.class.defaults[:max_items])) errors << 'Cannot specify the field to use and its start value to paginate from when using a fix pager (i.e., `by` and/or `from` params are not compabible with `page`)' if page && (by || from) if by && self.class.fields_allowed && !self.class.fields_allowed.include?(by.to_sym) errors << if self.class.media_type.attributes.key?(by.to_sym) "Paginating by field \'#{by}\' is disallowed" else "Paginating by field \'#{by}\' is not possible as this field does not exist in "\ "media type #{self.class.media_type.name}" end end errors end |