toqua 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []