toqua 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 43a5f057196fff4c8cd5b4b182eae2e1f53ea7b7
4
+ data.tar.gz: db0835906e1e11b74eec8dda63519326684be04a
5
+ SHA512:
6
+ metadata.gz: a2beeb545bf067166984712a900ecbce55e4ece2828bb844b4aab65f27950990856d4f87e53737522613f0ae1ef2f6d6155ac9868a7662ee9e219071f5784e53
7
+ data.tar.gz: bd3b513750b11822c272e037be436126f9c9a209a2fd7821680fb3ce7d138c22b71aefca3253c6e8674a22d018fcdae5aec66e7a30d864c7e42a3fa22355e9a0
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ log/*
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ sudo: false
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.1.8
6
+ - 2.2.4
7
+ - 2.3.0
8
+ - 2.4.0
9
+ before_install: gem install bundler -v 1.15.4
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in toqua.gemspec
6
+ gemspec
data/README.md ADDED
@@ -0,0 +1,304 @@
1
+ # Toqua
2
+
3
+ [![Build Status](https://travis-ci.org/rogercampos/toqua.svg?branch=master)](https://travis-ci.org/rogercampos/toqua)
4
+
5
+ Collection of controller utilities for rails applications. Created with the intention of bringing back most of the nice things
6
+ about inherited resources, but in a more simple and explicit way.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'toqua'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install toqua
23
+
24
+ ## Usage
25
+
26
+ This library contain different tools that can be used independently, described below.
27
+
28
+ ### Transform params
29
+
30
+ Use this to change the value of a `params` key, for example:
31
+
32
+ ```ruby
33
+ class MyController < ApplicationController
34
+ include Toqua::TransformParams
35
+ transform_params(:q) { |v| JSON.parse(v) }
36
+ end
37
+ ```
38
+
39
+ This would transform the value of `params[:q]` from a raw string into its json representation. The new value is whatever returns your block. Also works on nested keys:
40
+
41
+ `transform_params(user: :q) {|v| DataManipulation.change(v) }`
42
+
43
+ Or more levels of nesting:
44
+
45
+ `transform_params(user: {data: :q}) {|v| DataManipulation.change(v) }`
46
+
47
+
48
+ ### Scoping
49
+
50
+ This allows you to further refine an `ActiveRecord::Relation`, optionally depending on conditionals. For example:
51
+
52
+
53
+ ```ruby
54
+ class MyController < ApplicationController
55
+ include Toqua::Scoping
56
+
57
+ scope {|s| s.where(parent_id: params[:parent_id])}
58
+
59
+ def index
60
+ @elements = apply_scopes(Element)
61
+ end
62
+ end
63
+ ```
64
+
65
+ The `scope` definitions are lambdas that receive an `ActiveRecord::Relation` as parameter and must return another
66
+ `AR::Relation`. They are chained in the order they're defined. To use them, you explicitly call `apply_scopes` with the initial
67
+ argument.
68
+
69
+ You can use `:if` or `:unless` to conditionally choose if execute the scope or not. Examples:
70
+
71
+ `scope(if: :show_all?) { |s| s.includes(:a, :b) }`
72
+
73
+ This will call the method `show_all?` defined in the controller and their return value (truthy or falsey) will indicate if the scope
74
+ applies or not. You can also use anything that responds to `:call` directly, ex:
75
+
76
+ `scope(if: -> { false }) { |s| s.all }`
77
+
78
+ Finally, you can also condition the scope execution based on the action on the controller:
79
+
80
+ `scope(only: :index) { |s| s.includes(:a, :b) }`
81
+
82
+ This is the foundation used to build searching, sorting and pagination over an `AR::Relation`.
83
+
84
+ Used as an independent tool, it provides a way to define scopes used by multiple actions in the same place (authorization, eager loading, etc.).
85
+
86
+
87
+ ### Pagination
88
+
89
+ This tool can be used to paginate collections using [Kaminari](https://github.com/kaminari/kaminari), providing some additional useful things. Example of basic usage:
90
+
91
+ ```ruby
92
+ class MyController < ApplicationController
93
+ include Toqua::Pagination
94
+
95
+ paginate
96
+
97
+ def index
98
+ @elements = apply_scopes(Element)
99
+ end
100
+ end
101
+ ```
102
+
103
+ As the `paginate` method uses scoping, you can pass the options of `:if, :unless and :action` that will get forwarded to the `scope` method, allowing
104
+ you to conditionally decide when to paginate. Ex:
105
+
106
+ `paginate(only: :index)`
107
+
108
+ Or, to paginate only on html but not xlsx format:
109
+
110
+ `paginate(unless: :xlsx?)`
111
+
112
+ The names of the url parameters used to identify the current page and the number of results per page are `page` and `per_page` by default, but can be changed using:
113
+
114
+ `paginate(page_key: "page", per_page_key: "per_page")`
115
+
116
+ The number of results in each page can be controlled with the `:per` option:
117
+
118
+ `paginate(per: 100)`
119
+
120
+ The last option available is `:headers`. If used, 3 additional headers will be attached into the response allowing you to know info about the pagination of the collection. This is useful for API clients. Ex:
121
+
122
+ `paginate(headers: true)`
123
+
124
+ The response will include the following headers:
125
+
126
+ - 'X-Pagination-Total': Total number of elements in the collection without pagination
127
+ - 'X-Pagination-Per-Page': Number of elements per page
128
+ - 'X-Pagination-Page': Number of the current page
129
+
130
+ Finally, the method `paginated?` available in both the controller and the views will tell you if the collection has been paginated or not.
131
+
132
+
133
+ ### Search
134
+
135
+ Small utility to help in the implementation of searching, using [Doure](https://github.com/rogercampos/doure) as a way to filter an AR model. Given that you have a model with filters defined, ex:
136
+
137
+ ```ruby
138
+ class Post < ApplicationRecord
139
+ extend Doure::Filterable
140
+ filter_class PostFilter
141
+ end
142
+
143
+ class PostFilter
144
+ cont_filter(:title)
145
+ cont_filter(:slug)
146
+ present_filter(:scheduled_at)
147
+ eq_filter(:id)
148
+ filter(:category_id_eq) { |s, value| s.joins(:post_categories).where(post_categories: {category_id: value}) }
149
+ end
150
+ ```
151
+
152
+ You can setup searching in the controller using:
153
+
154
+
155
+ ```ruby
156
+ class PostsController < ApplicationController
157
+ include Toqua::Search
158
+
159
+ searchable
160
+
161
+ def index
162
+ @elements = apply_scopes(Post)
163
+ end
164
+ end
165
+ ```
166
+
167
+ The parameter used to represent the search criteria is `:q`.
168
+
169
+ The method `search_params` will give you a hash representing the contents of `:q`, which is the current search criteria, for example:
170
+
171
+ `{title_cont: "Air", category_id_eq: "12", slug_cont: "", scheduled_at_present: "", id_eq: ""}`
172
+
173
+ The method `active_search_params` will give you only the search parameters containing some value:
174
+
175
+ `{title_cont: "Air", category_id_eq: "12"}`
176
+
177
+ The method `search_object`, available in the view, gives an `ActiveModel` like object stuffed with the current `search_params`, so you can use that as the object
178
+ of the search form to automatically pre-fill all the search inputs with their current value. Ex:
179
+
180
+ ```slim
181
+ = form_for search_object do |f|
182
+ = f.input :title_cont
183
+ = f.input :category_id_eq, collection: ...
184
+ ```
185
+
186
+ The method `searching?` will tell you if there's a current search or not.
187
+
188
+ Finally, you can define a `default_search_params` method in the controller to setup default search criteria:
189
+
190
+ ```ruby
191
+ def default_search_params
192
+ { visible_by_role: "editor" }
193
+ end
194
+ ```
195
+
196
+
197
+
198
+ ### Sorting
199
+
200
+ The sorting utility allows you to sort the collection, using the parameter `s` in the url with a format like `title+asc` or `title+desc`. Usage example:
201
+
202
+ ```ruby
203
+ class PostsController < ApplicationController
204
+ include Toqua::Sorting
205
+
206
+ sorting
207
+
208
+ def index
209
+ @elements = apply_scopes(Post)
210
+ end
211
+ end
212
+ ```
213
+
214
+ A helper to create sorting links easily is not directly provided by the gem, but can be something like this:
215
+
216
+ ```ruby
217
+ def sort_link(name, label = nil, opts = {})
218
+ label ||= name.to_s.humanize
219
+ current_attr_name, current_direction = params[:s].present? && params[:s].split("+").map(&:strip)
220
+
221
+ next_direction = opts.fetch(:default_order, current_direction == "asc" ? "desc" : "asc")
222
+
223
+ parameters = request.query_parameters
224
+ parameters.merge!(opts[:link_params]) if opts[:link_params]
225
+
226
+ dest_url = url_for(parameters.merge(s: "#{name}+#{next_direction}"))
227
+ direction_icon = current_direction == "asc" ? "↑" : "↓"
228
+ anchor = current_attr_name == name.to_s ? "#{label} #{direction_icon}" : label
229
+
230
+ link_opts = opts.fetch(:link_opts, {})
231
+
232
+ link_to(anchor, dest_url, link_opts)
233
+ end
234
+ ```
235
+
236
+ Then used as:
237
+
238
+ `= sort_link :title, "Title"`
239
+
240
+ ### Keyset pagination
241
+
242
+ The keyset pagination is similar to the pagination utility, but working with [OrderQuery](https://github.com/glebm/order_query) to provide pagination that works with no offsets. Example usage:
243
+
244
+ ```ruby
245
+ class PostsController < ApplicationController
246
+ include Toqua::KeysetPagination
247
+
248
+ keyset_paginate :score_order
249
+
250
+ def index
251
+ @elements = apply_scopes(Post)
252
+ end
253
+ end
254
+ ```
255
+
256
+ It takes care of applying the correct scoping based on the id of the current element, as identified by the `:idx` parameter as default. With the optional `:headers` parameter some headers are also added into the response:
257
+
258
+ `keyset_paginate :score_order, headers: true`
259
+
260
+ Will generate those headers:
261
+
262
+ - `'X-KeysetPagination-Index'`: The `id` of the current element index.
263
+ - `'X-KeysetPagination-Next-Index'`: The `id` of the element to use as the next page.
264
+ - `'X-KeysetPagination-Prev-Index'`: The `id` of the element to use as the previous page.
265
+
266
+ The next and prev indexes are also available via the instance vars `@keyset_pagination_prev_index` and `@keyset_pagination_next_index`.
267
+
268
+ If the value of `@keyset_pagination_prev_index` (or via header) is `-1` it means the previous page is the initial one. If it's `nil`, there's no previous page.
269
+
270
+ To generate pagination links, you can use something like this:
271
+
272
+ ```ruby
273
+ def keyset_pagination_next_link(index_key = :idx)
274
+ if @keyset_pagination_next_index
275
+ url_for(request.GET.merge(index_key => @keyset_pagination_next_index))
276
+ end
277
+ end
278
+
279
+ def keyset_pagination_prev_link(index_key = :idx)
280
+ if @keyset_pagination_prev_index
281
+ if @keyset_pagination_prev_index == -1
282
+ url_for(request.GET.merge(index_key => nil))
283
+ else
284
+ url_for(request.GET.merge(index_key => @keyset_pagination_prev_index))
285
+ end
286
+ end
287
+ end
288
+ ```
289
+
290
+ ### Final notes
291
+
292
+ If you use multiple scope declarations either mixed with the other utilities shown here or not, be aware of the order. For example, pagination must
293
+ always go last.
294
+
295
+
296
+ ## Development
297
+
298
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
299
+
300
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
301
+
302
+ ## Contributing
303
+
304
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/toqua.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "toqua"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,63 @@
1
+ module Toqua
2
+ module KeysetPagination
3
+ extend ActiveSupport::Concern
4
+ include Scoping
5
+
6
+ DEFAULT_INDEX_KEY = :idx
7
+ DEFAULT_PER_PAGE = 30
8
+
9
+ included do
10
+ helper_method :paginated?
11
+ end
12
+
13
+ def paginated?
14
+ @paginated
15
+ end
16
+
17
+ class_methods do
18
+ def keyset_paginate(order_query_name, opts = {})
19
+ opts.assert_valid_keys(:per, :index_key, :headers)
20
+ per = opts.fetch(:per, DEFAULT_PER_PAGE)
21
+ index_key = opts.fetch(:index_key, DEFAULT_INDEX_KEY)
22
+
23
+ scope do |scope|
24
+ idx = params[index_key].presence
25
+
26
+ if idx
27
+ current_object = scope.model.find_by(id: idx)
28
+ end
29
+
30
+ current_object ||= scope.send(order_query_name).first
31
+
32
+ if current_object # Only in case there are no objects to paginate
33
+ @paginated = true
34
+
35
+ point = scope.model.send("#{order_query_name}_at", current_object)
36
+
37
+ two_previous_points = point.before.merge(scope.except(:order, :preload, :eager_load)).offset(per - 1).limit(2).to_a
38
+
39
+ if two_previous_points.empty?
40
+ @keyset_pagination_prev_index = nil
41
+ elsif two_previous_points.size == 1
42
+ @keyset_pagination_prev_index = -1
43
+ else
44
+ @keyset_pagination_prev_index = two_previous_points.first.id
45
+ end
46
+
47
+ @keyset_pagination_next_index = point.after.merge(scope.except(:order, :preload, :eager_load)).offset(per - 1).first.try(:id)
48
+
49
+ if opts[:headers]
50
+ headers['X-KeysetPagination-Index'] = current_object.id
51
+ headers['X-KeysetPagination-Next-Index'] = @keyset_pagination_next_index
52
+ headers['X-KeysetPagination-Prev-Index'] = @keyset_pagination_prev_index
53
+ end
54
+
55
+ scope.except(:order).merge(point.after(false).limit(per)).send(order_query_name)
56
+ else
57
+ scope
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,44 @@
1
+ module Toqua
2
+ module Pagination
3
+ extend ActiveSupport::Concern
4
+ include Scoping
5
+
6
+ DEFAULT_PAGE = 1
7
+ DEFAULT_PAGE_KEY = :page
8
+ DEFAULT_PER_PAGE = 30
9
+ DEFAULT_PER_PAGE_KEY = :per_page
10
+
11
+ included do
12
+ helper_method :paginated?
13
+ end
14
+
15
+ def paginated?
16
+ @paginated
17
+ end
18
+
19
+ class_methods do
20
+ def paginate(opts = {})
21
+ page_key = opts.fetch(:page_key, DEFAULT_PAGE_KEY)
22
+ per_page_key = opts.fetch(:per_page_key, DEFAULT_PER_PAGE_KEY)
23
+
24
+ scope_opts = opts.slice(:if, :unless, :only)
25
+
26
+ scope(scope_opts) do |scope|
27
+ @paginated = true
28
+
29
+ @page = params.fetch(page_key, opts.fetch(:page, DEFAULT_PAGE))
30
+ per = params.fetch(per_page_key, opts.fetch(:per, DEFAULT_PER_PAGE))
31
+
32
+ if opts[:headers]
33
+ scope_count = scope.count
34
+ headers['X-Pagination-Total'] = scope_count.is_a?(Hash) ? scope_count.keys.count.to_s : scope_count.to_s
35
+ headers['X-Pagination-Per-Page'] = per.to_s
36
+ headers['X-Pagination-Page'] = @page.to_s
37
+ end
38
+
39
+ per == '0' ? scope : scope.page(@page).per(per)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,46 @@
1
+ module Toqua
2
+ module Scoping
3
+ extend ActiveSupport::Concern
4
+
5
+ def apply_scopes(start)
6
+ s = start
7
+ self.class.__scopes.each do |scope, opts|
8
+ s = __run_scope(s, scope, opts)
9
+ end
10
+ s
11
+ end
12
+
13
+ def __run_scope(relation, scope, opts)
14
+ if_condition = if opts[:if]
15
+ opts[:if].respond_to?(:call) ? !!instance_exec(&opts[:if]) : send(opts[:if])
16
+ elsif opts[:unless]
17
+ opts[:unless].respond_to?(:call) ? !instance_exec(&opts[:unless]) : !send(opts[:unless])
18
+ else
19
+ true
20
+ end
21
+
22
+ action_condition = if opts[:only]
23
+ [opts[:only]].flatten.include?(action_name.to_sym)
24
+ else
25
+ true
26
+ end
27
+
28
+ if if_condition && action_condition
29
+ self.instance_exec(relation, &scope)
30
+ else
31
+ relation
32
+ end
33
+ end
34
+
35
+ included do
36
+ class_attribute(:__scopes)
37
+ self.__scopes = []
38
+ end
39
+
40
+ class_methods do
41
+ def scope(opts = {}, &block)
42
+ self.__scopes += [[block, opts]]
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,45 @@
1
+ module Toqua
2
+ module Search
3
+ extend ActiveSupport::Concern
4
+ include Scoping
5
+
6
+ included do
7
+ helper_method :search_params, :searching?, :search_object, :active_search_params
8
+ end
9
+
10
+ def search_params
11
+ params[:q].permit!
12
+ (params[:q] || {}).to_h.reverse_merge(default_search_params)
13
+ end
14
+
15
+ def active_search_params
16
+ search_params.select { |_, b| !b.nil? && b != "" }.to_h
17
+ end
18
+
19
+ def search_object
20
+ @search_object ||= begin
21
+ Class.new(Hashie::Mash) do
22
+ extend ActiveModel::Naming
23
+
24
+ def self.model_name
25
+ ActiveModel::Name.new(Class, nil, "q")
26
+ end
27
+ end.new(search_params)
28
+ end
29
+ end
30
+
31
+ def searching?
32
+ params.key?(:q)
33
+ end
34
+
35
+ def default_search_params
36
+ {}
37
+ end
38
+
39
+ class_methods do
40
+ def searchable
41
+ scope { |s| s.filter(search_params) }
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,25 @@
1
+ module Toqua
2
+ module Sorting
3
+ extend ActiveSupport::Concern
4
+
5
+ class_methods do
6
+ def sorting(opts = {})
7
+ reorder = opts.fetch(:reorder, true)
8
+
9
+ scope do |s|
10
+ if params[:s].present?
11
+ attr_name, direction = params[:s].to_s.split("+").map(&:strip)
12
+ raise "You must provide an attribute to sort by" unless attr_name
13
+ raise "You must provide a direction" unless direction
14
+ direction.downcase!
15
+ raise "Direction must be ASC or DESC" unless ["asc", "desc"].include?(direction)
16
+
17
+ s.send(reorder ? :reorder : :order, s.arel_table[attr_name].send(direction))
18
+ else
19
+ s
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,38 @@
1
+ module Toqua
2
+ module TransformParams
3
+ extend ActiveSupport::Concern
4
+
5
+ class ParameterConverter
6
+ def parse(params, hash, block)
7
+ if Hash === hash
8
+ key = hash.keys.first
9
+
10
+ if params.key?(key)
11
+ parse(params[key], hash[key], block)
12
+ end
13
+ else
14
+ if params.key?(hash)
15
+ params[hash] = block.call(params[hash])
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ included do
22
+ class_attribute(:__transform_params)
23
+ self.__transform_params = []
24
+
25
+ prepend_before_action do
26
+ self.class.__transform_params.each do |hash, block|
27
+ ParameterConverter.new.parse(params, hash, block)
28
+ end
29
+ end
30
+ end
31
+
32
+ class_methods do
33
+ def transform_params(hash, &block)
34
+ self.__transform_params += [[hash, block]]
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module Toqua
2
+ VERSION = "0.1.0"
3
+ end
data/lib/toqua.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "toqua/version"
2
+
3
+ require 'active_support/all'
4
+
5
+ require 'toqua/scoping'
6
+ require 'toqua/pagination'
7
+ require 'toqua/search'
8
+ require 'toqua/sorting'
9
+ require 'toqua/transform_params'
10
+ require 'toqua/keyset_pagination'
11
+
12
+
13
+ module Toqua
14
+ # Your code goes here...
15
+ end
data/toqua.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "toqua/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "toqua"
8
+ spec.version = Toqua::VERSION
9
+ spec.authors = ["Roger Campos"]
10
+ spec.email = ["roger@rogercampos.com"]
11
+
12
+ spec.summary = %q{Collection of small utilities for controllers in rails applications}
13
+ spec.description = %q{Collection of small utilities for controllers in rails applications}
14
+ spec.homepage = "https://github.com/rogercampos/toqua"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "activesupport", ">= 4.0.0"
24
+ spec.add_dependency "actionpack", ">= 4.0.0"
25
+ spec.add_dependency "activerecord", ">= 4.0.0"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.15"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "minitest", "~> 5.0"
30
+ spec.add_development_dependency "minitest-rails"
31
+ spec.add_development_dependency "sqlite3"
32
+ spec.add_development_dependency "order_query", ">= 0.3.4"
33
+ end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: toqua
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Roger Campos
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-08-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 4.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionpack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 4.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 4.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 4.0.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 4.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.15'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.15'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '5.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest-rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: sqlite3
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: order_query
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: 0.3.4
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: 0.3.4
139
+ description: Collection of small utilities for controllers in rails applications
140
+ email:
141
+ - roger@rogercampos.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".gitignore"
147
+ - ".travis.yml"
148
+ - Gemfile
149
+ - README.md
150
+ - Rakefile
151
+ - bin/console
152
+ - bin/setup
153
+ - lib/toqua.rb
154
+ - lib/toqua/keyset_pagination.rb
155
+ - lib/toqua/pagination.rb
156
+ - lib/toqua/scoping.rb
157
+ - lib/toqua/search.rb
158
+ - lib/toqua/sorting.rb
159
+ - lib/toqua/transform_params.rb
160
+ - lib/toqua/version.rb
161
+ - toqua.gemspec
162
+ homepage: https://github.com/rogercampos/toqua
163
+ licenses: []
164
+ metadata: {}
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 2.5.2
182
+ signing_key:
183
+ specification_version: 4
184
+ summary: Collection of small utilities for controllers in rails applications
185
+ test_files: []