boosted-rails 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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +30 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +240 -0
- data/LICENSE.txt +21 -0
- data/README.md +563 -0
- data/Rakefile +12 -0
- data/boosted.gemspec +33 -0
- data/lib/boosted/controllers/filterable.rb +141 -0
- data/lib/boosted/controllers/pageable.rb +130 -0
- data/lib/boosted/controllers/searchable.rb +162 -0
- data/lib/boosted/controllers/sortable.rb +115 -0
- data/lib/boosted/controllers/tabulatable.rb +91 -0
- data/lib/boosted/emails/.keep +0 -0
- data/lib/boosted/jobs/base.rb +23 -0
- data/lib/boosted/queries/filter.rb +91 -0
- data/lib/boosted/queries/paginate.rb +100 -0
- data/lib/boosted/queries/search.rb +62 -0
- data/lib/boosted/queries/sort.rb +90 -0
- data/lib/boosted/railtie.rb +9 -0
- data/lib/boosted/services/base.rb +94 -0
- data/lib/boosted/tasks/bosted.rake +10 -0
- data/lib/boosted/tasks/templates/initializer.rb +8 -0
- data/lib/boosted/version.rb +5 -0
- data/lib/boosted.rb +31 -0
- data/sig/boosted.rbs +4 -0
- metadata +108 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "boosted/services/base"
|
4
|
+
|
5
|
+
module Boosted
|
6
|
+
module Queries
|
7
|
+
##
|
8
|
+
# Filter a scope by a set of conditions
|
9
|
+
#
|
10
|
+
# This class provides a simple interface for filtering a scope by a set of conditions.
|
11
|
+
# The conditions are passed as an array of hashes, where each hash contains the following
|
12
|
+
# keys:
|
13
|
+
# - +relation+: the relation to use for the filter (e.g. "=", ">", "in", etc.)
|
14
|
+
# - +field+: the field to filter by
|
15
|
+
# - +value+: the value to filter by
|
16
|
+
#
|
17
|
+
#
|
18
|
+
# @example Filter a scope by a set of conditions
|
19
|
+
# Boosted::Queries::Filter.call(User.all, filter_conditions: [
|
20
|
+
# { relation: "=", field: :first_name, value: "John" },
|
21
|
+
# { relation: ">", field: :age, value: 18 }
|
22
|
+
# ])
|
23
|
+
# # => #<ActiveRecord::Relation [...]>
|
24
|
+
#
|
25
|
+
# @see RELATIONS
|
26
|
+
# To see the list of available relations, check the +RELATIONS+ constant.
|
27
|
+
class Filter
|
28
|
+
RELATIONS = %w[= != > >= < <= between in not_in starts_with ends_with contains is_null is_not_null].freeze
|
29
|
+
|
30
|
+
# @param scope [ActiveRecord::Relation] the scope to filter
|
31
|
+
# @param filter_conditions [Array<Hash>] the conditions to filter by
|
32
|
+
# @return [ActiveRecord::Relation] the filtered scope
|
33
|
+
def self.call(scope, filter_conditions:)
|
34
|
+
new(scope, filter_conditions:).call
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param scope [ActiveRecord::Relation] the scope to filter
|
38
|
+
# @param filter_conditions [Array<Hash>] the conditions to filter by
|
39
|
+
# @return [ActiveRecord::Relation] the filtered scope
|
40
|
+
def initialize(scope, filter_conditions:)
|
41
|
+
super()
|
42
|
+
@scope = scope
|
43
|
+
@filter_conditions = filter_conditions
|
44
|
+
end
|
45
|
+
|
46
|
+
def call
|
47
|
+
filter_conditions.reduce(scope) do |scope, filter_condition|
|
48
|
+
relation = filter_condition[:relation].to_s
|
49
|
+
field = filter_condition[:field]
|
50
|
+
value = filter_condition[:value]
|
51
|
+
|
52
|
+
validate_relation!(relation)
|
53
|
+
filtered_scope(scope, relation, field, value)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
attr_reader :scope, :filter_conditions
|
60
|
+
|
61
|
+
def validate_relation!(relation)
|
62
|
+
return if RELATIONS.include?(relation)
|
63
|
+
|
64
|
+
raise ArgumentError, "relation must be one of: #{RELATIONS.join(", ")}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def filtered_scope(scope, relation, field, value)
|
68
|
+
case relation
|
69
|
+
when "=", "in"
|
70
|
+
scope.where(field => value)
|
71
|
+
when "!=", "not_in"
|
72
|
+
scope.where.not(field => value)
|
73
|
+
when "between"
|
74
|
+
scope.where("#{field} BETWEEN ? AND ?", value.first, value.last)
|
75
|
+
when "starts_with"
|
76
|
+
scope.where("#{field} LIKE ?", "#{value}%")
|
77
|
+
when "ends_with"
|
78
|
+
scope.where("#{field} LIKE ?", "%#{value}")
|
79
|
+
when "contains"
|
80
|
+
scope.where("#{field} LIKE ?", "%#{value}%")
|
81
|
+
when "is_null"
|
82
|
+
scope.where(field => nil)
|
83
|
+
when "is_not_null"
|
84
|
+
scope.where.not(field => nil)
|
85
|
+
else # '>', '>=', '<', '<='
|
86
|
+
scope.where("#{field} #{relation} ?", value)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "boosted/services/base"
|
4
|
+
|
5
|
+
module Boosted
|
6
|
+
module Queries
|
7
|
+
##
|
8
|
+
# Paginate a scope
|
9
|
+
#
|
10
|
+
# This class provides a way to paginate a scope and return the metadata.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# Boosted::Queries::Paginate.call(User.all, page: 2, per_page: 10)
|
14
|
+
# # => [{ total_count: 100, total_pages: 10, next_page: 3, prev_page: 1, page: 2, per_page: 10 }, <ActiveRecord::Relation [...]>]
|
15
|
+
#
|
16
|
+
# @see MAX_PER_PAGE
|
17
|
+
# @see DEFAULT_PER_PAGE
|
18
|
+
# To see the maximum number of records per page and the default number of records per page,
|
19
|
+
# check the +MAX_PER_PAGE+ and +DEFAULT_PER_PAGE+ constants.
|
20
|
+
class Paginate
|
21
|
+
MAX_PER_PAGE = 100
|
22
|
+
DEFAULT_PER_PAGE = 10
|
23
|
+
|
24
|
+
# @param scope [ActiveRecord::Relation] the scope to paginate
|
25
|
+
# @param page [Integer] the page number
|
26
|
+
# @param per_page [Integer] the number of records per page
|
27
|
+
# @return [Array<Hash, ActiveRecord::Relation>] the metadata and the paginated scope
|
28
|
+
def self.call(scope, page: nil, per_page: nil)
|
29
|
+
new(scope, page:, per_page:).call
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param scope [ActiveRecord::Relation] the scope to paginate
|
33
|
+
# @param page [Integer] the page number
|
34
|
+
# @param per_page [Integer] the number of records per page
|
35
|
+
# @return [Array<Hash, ActiveRecord::Relation>] the metadata and the paginated scope
|
36
|
+
def initialize(scope, page: nil, per_page: nil)
|
37
|
+
super()
|
38
|
+
@scope = scope
|
39
|
+
@page = page
|
40
|
+
@per_page = per_page
|
41
|
+
end
|
42
|
+
|
43
|
+
def call
|
44
|
+
offset = (page - 1) * per_page
|
45
|
+
paginated_scope = scope.limit(per_page).offset(offset)
|
46
|
+
|
47
|
+
[metadata(scope), paginated_scope]
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
attr_reader :scope
|
53
|
+
|
54
|
+
def page
|
55
|
+
@page.present? ? @page.to_i : 1
|
56
|
+
end
|
57
|
+
|
58
|
+
def per_page
|
59
|
+
@per_page.present? ? [@per_page.to_i, MAX_PER_PAGE].min : DEFAULT_PER_PAGE
|
60
|
+
end
|
61
|
+
|
62
|
+
def collection_count(scope)
|
63
|
+
if scope.group_values.empty?
|
64
|
+
scope.count(:all)
|
65
|
+
else
|
66
|
+
sql = Arel.star.count.over(Arel::Nodes::Grouping.new([]))
|
67
|
+
scope.unscope(:order).pick(sql).to_i
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def metadata(scope)
|
72
|
+
total_count = collection_count(scope)
|
73
|
+
total_pages = pages(total_count, per_page)
|
74
|
+
next_page = next_page(page, total_pages)
|
75
|
+
prev_page = prev_page(page)
|
76
|
+
|
77
|
+
{
|
78
|
+
total_count:,
|
79
|
+
total_pages:,
|
80
|
+
next_page:,
|
81
|
+
prev_page:,
|
82
|
+
page:,
|
83
|
+
per_page:
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def pages(count, per_page)
|
88
|
+
(count.to_f / per_page).ceil
|
89
|
+
end
|
90
|
+
|
91
|
+
def next_page(page, pages)
|
92
|
+
page < pages ? page + 1 : nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def prev_page(page)
|
96
|
+
page > 1 ? page - 1 : nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "boosted/services/base"
|
4
|
+
|
5
|
+
module Boosted
|
6
|
+
module Queries
|
7
|
+
##
|
8
|
+
# Search for records in a scope
|
9
|
+
#
|
10
|
+
# This class provides a way to search for records in a scope.
|
11
|
+
# It uses a scope in the model to perform the search.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# Boosted::Queries::Search.call(User.all, search_term: "John")
|
15
|
+
# # => #<ActiveRecord::Relation [...]>
|
16
|
+
#
|
17
|
+
# By default, it uses the +search+ scope in the model to perform the search.
|
18
|
+
# You can also specify a different scope to use for searching, like so:
|
19
|
+
# @example
|
20
|
+
# Boosted::Queries::Search.call(User.all, search_term: "John", model_search_scope: :search_by_name)
|
21
|
+
# # => #<ActiveRecord::Relation [...]>
|
22
|
+
#
|
23
|
+
class Search
|
24
|
+
# @param scope [ActiveRecord::Relation] the scope to search in
|
25
|
+
# @param search_term [String] the term to search for
|
26
|
+
# @param model_search_scope [String, Symbol] the name of the scope to use for searching in the model
|
27
|
+
# @return [ActiveRecord::Relation] the searched scope
|
28
|
+
def self.call(scope, search_term:, model_search_scope: :search)
|
29
|
+
new(scope, search_term:, model_search_scope:).call
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param scope [ActiveRecord::Relation] the scope to search in
|
33
|
+
# @param search_term [String] the term to search for
|
34
|
+
# @param model_search_scope [String, Symbol] the name of the scope to use for searching in the model
|
35
|
+
# @return [ActiveRecord::Relation] the searched scope
|
36
|
+
def initialize(scope, search_term:, model_search_scope: :search)
|
37
|
+
super()
|
38
|
+
@scope = scope
|
39
|
+
@search_term = search_term
|
40
|
+
@model_search_scope = model_search_scope
|
41
|
+
end
|
42
|
+
|
43
|
+
def call
|
44
|
+
return scope if search_term.blank?
|
45
|
+
|
46
|
+
validate_model_search_scope!
|
47
|
+
|
48
|
+
scope.public_send(model_search_scope, search_term)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
attr_reader :scope, :search_term, :model_search_scope
|
54
|
+
|
55
|
+
def validate_model_search_scope!
|
56
|
+
return if scope.respond_to?(model_search_scope)
|
57
|
+
|
58
|
+
raise ArgumentError, "#{scope.klass} does not respond to #{model_search_scope}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "boosted/services/base"
|
4
|
+
|
5
|
+
module Boosted
|
6
|
+
module Queries
|
7
|
+
##
|
8
|
+
# Sorts a scope by a given key and direction
|
9
|
+
#
|
10
|
+
# This class provides a way to sort a scope by a given key and direction.
|
11
|
+
# It uses the +reorder+ method to sort the scope, so it will remove any existing order.
|
12
|
+
#
|
13
|
+
# @example Sort a scope by a key and direction
|
14
|
+
# Boosted::Queries::Sort.call(User.all, sort_key: "name", sort_direction: "asc")
|
15
|
+
# # => #<ActiveRecord::Relation [...]>
|
16
|
+
#
|
17
|
+
# @example Sort a scope by a key with format +table.column+ and direction
|
18
|
+
# Boosted::Queries::Sort.call(User.join(:accounts), sort_key: "accounts.updated_at", sort_direction: "asc")
|
19
|
+
# # => #<ActiveRecord::Relation [...]>
|
20
|
+
class Sort
|
21
|
+
SORT_DIRECTIONS = %w[asc desc].freeze
|
22
|
+
NULLS_SORT_DIRECTION = %w[asc_nulls_first asc_nulls_last desc_nulls_first desc_nulls_last].freeze
|
23
|
+
|
24
|
+
# @param scope [ActiveRecord::Relation] the scope to sort
|
25
|
+
# @param sort_key [String, Symbol] the key to sort by
|
26
|
+
# @param sort_direction [String, Symbol] the direction to sort by
|
27
|
+
# @return [ActiveRecord::Relation] the sorted scope
|
28
|
+
def self.call(scope, sort_key:, sort_direction: :desc)
|
29
|
+
new(scope, sort_key:, sort_direction:).call
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param scope [ActiveRecord::Relation] the scope to sort
|
33
|
+
# @param sort_key [String, Symbol] the key to sort by
|
34
|
+
# @param sort_direction [String, Symbol] the direction to sort by
|
35
|
+
# @return [ActiveRecord::Relation] the sorted scope
|
36
|
+
def initialize(scope, sort_key:, sort_direction: :desc)
|
37
|
+
super()
|
38
|
+
@scope = scope
|
39
|
+
@sort_key = sort_key.to_s
|
40
|
+
@sort_direction = sort_direction.to_s.downcase
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [ActiveRecord::Relation]
|
44
|
+
def call
|
45
|
+
validate_sort_direction!(sort_direction)
|
46
|
+
|
47
|
+
order = if NULLS_SORT_DIRECTION.include?(sort_direction)
|
48
|
+
arel_order
|
49
|
+
else
|
50
|
+
{ sort_key => sort_direction }
|
51
|
+
end
|
52
|
+
|
53
|
+
scope.reorder(order)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
attr_reader :scope, :sort_key, :sort_direction
|
59
|
+
|
60
|
+
def validate_sort_direction!(sort_direction)
|
61
|
+
return if SORT_DIRECTIONS.include?(sort_direction) || NULLS_SORT_DIRECTION.include?(sort_direction)
|
62
|
+
|
63
|
+
raise ArgumentError, "Invalid sort direction: #{sort_direction}, must be one of #{SORT_DIRECTIONS}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def arel_order
|
67
|
+
arel_table.send(order_nulls_direction.first).send("nulls_#{order_nulls_direction.last}")
|
68
|
+
end
|
69
|
+
|
70
|
+
def arel_table
|
71
|
+
sort_key_arr = sort_key.split(".")
|
72
|
+
|
73
|
+
if sort_key_arr.size == 1
|
74
|
+
# sort_key has format 'column'
|
75
|
+
scope.klass.arel_table[sort_key]
|
76
|
+
else
|
77
|
+
# sort_key has format 'table.column'
|
78
|
+
Arel::Table.new(sort_key_arr.first)[sort_key_arr.last]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def order_nulls_direction
|
83
|
+
@order_nulls_direction ||= begin
|
84
|
+
order_nulls_dir = sort_direction.split("_")
|
85
|
+
[order_nulls_dir.first, order_nulls_dir.last]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "boosted/jobs/base"
|
4
|
+
|
5
|
+
module Boosted
|
6
|
+
module Services
|
7
|
+
# Base class for all services
|
8
|
+
#
|
9
|
+
# This class provides a simple interface for creating services.
|
10
|
+
# It also provides a way to call services asynchronously using +ActiveJob+.
|
11
|
+
#
|
12
|
+
# @example Create a service
|
13
|
+
# class PrintService < Boosted::Services::Base
|
14
|
+
# def call(message)
|
15
|
+
# puts message
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# SomeService.call('Hello World') # => "Hello World"
|
20
|
+
# SomeService.new('Hello World').call # => "Hello World"
|
21
|
+
#
|
22
|
+
# @example Call a service asynchronously
|
23
|
+
# class SlowService < Boosted::Services::Base
|
24
|
+
# enable_job!
|
25
|
+
#
|
26
|
+
# def call(message)
|
27
|
+
# sleep 5
|
28
|
+
# puts message
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# SlowService.call_later('Hello World') # => "Hello World" after 5 seconds
|
33
|
+
# SlowService::Job.perform_later('Hello World') # => "Hello World" after 5 seconds
|
34
|
+
class Base
|
35
|
+
def self.call(...)
|
36
|
+
new(...).call
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.call_later(...)
|
40
|
+
unless @job_enabled
|
41
|
+
message = "#{self.class.name}::Job is not implemented, make sure to call enable_job! in the service"
|
42
|
+
raise NotImplementedError, message
|
43
|
+
end
|
44
|
+
|
45
|
+
self::Async.perform_later(...)
|
46
|
+
end
|
47
|
+
|
48
|
+
def call
|
49
|
+
raise NotImplementedError, "#{self.class.name}#call not implemented"
|
50
|
+
end
|
51
|
+
|
52
|
+
# This method is used to create a Job class that inherits from +Boosted::Jobs::Base+
|
53
|
+
# and calls the service asynchronously.
|
54
|
+
# @example Enable async for a service
|
55
|
+
# class SomeService < Bosted::Services::Base
|
56
|
+
# enable_job!
|
57
|
+
#
|
58
|
+
# def call(...)
|
59
|
+
# # service logic
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# # SomeService.call_later(...)
|
64
|
+
# # SomeService::Job.perform_later(...)
|
65
|
+
def self.enable_job!
|
66
|
+
@job_enabled = true
|
67
|
+
|
68
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
69
|
+
# class SomeService
|
70
|
+
# class Job < Boosted::Jobs::Base
|
71
|
+
#
|
72
|
+
# def perform(...)
|
73
|
+
# SomeService.call(...)
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# def self.call_later(...)
|
78
|
+
# Job.perform_later(...)
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
class Job < Boosted::Jobs::Base
|
82
|
+
def perform(...)
|
83
|
+
#{name}.call(...)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.call_later(...)
|
88
|
+
Job.perform_later(...)
|
89
|
+
end
|
90
|
+
RUBY
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :boosted do
|
4
|
+
task :install do
|
5
|
+
initializer_file = File.join(File.dirname(__FILE__), "templates", "boosted.rb.tt")
|
6
|
+
destination = "config/initializers/boosted.rb"
|
7
|
+
|
8
|
+
FileUtils.cp(initializer_file, destination)
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Boosted.configure do |config|
|
4
|
+
# Change the parent class of Boosted::Job::Base.
|
5
|
+
# This is useful if you want to use a different ActiveJob parent class.
|
6
|
+
# Default: 'ActiveJob::Base'
|
7
|
+
# config.base_job_parent_class = 'ActiveJob::Base'
|
8
|
+
end
|
data/lib/boosted.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/configurable"
|
4
|
+
|
5
|
+
##
|
6
|
+
# The main module for the Boosted gem.
|
7
|
+
#
|
8
|
+
# This module is used to provide configuration options for the gem.
|
9
|
+
#
|
10
|
+
# @example Configurations
|
11
|
+
# # config/initializers/boosted.rb
|
12
|
+
#
|
13
|
+
# Boosted.configure do |config|
|
14
|
+
# config.base_job_parent_class = "ApplicationJob" # Default: "ActiveJob::Base"
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# @see https://api.rubyonrails.org/classes/ActiveSupport/Configurable.html
|
18
|
+
#
|
19
|
+
module Boosted
|
20
|
+
include ActiveSupport::Configurable
|
21
|
+
|
22
|
+
config_accessor :base_job_parent_class, instance_accessor: false, default: "ActiveJob::Base"
|
23
|
+
end
|
24
|
+
|
25
|
+
# load all files in lib/boosted except for the tasks
|
26
|
+
require "zeitwerk"
|
27
|
+
loader = Zeitwerk::Loader.for_gem
|
28
|
+
loader.setup
|
29
|
+
loader.ignore("lib/boosted/tasks")
|
30
|
+
loader.ignore("lib/boosted/railtie.rb") unless defined?(Rails::Railtie)
|
31
|
+
loader.eager_load
|
data/sig/boosted.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: boosted-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Juan Aparicio
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-02-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '6.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '8.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '6.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '8.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: zeitwerk
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.4'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2.4'
|
47
|
+
description:
|
48
|
+
email:
|
49
|
+
- apariciojuan30@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- ".rspec"
|
55
|
+
- ".rubocop.yml"
|
56
|
+
- CHANGELOG.md
|
57
|
+
- CODE_OF_CONDUCT.md
|
58
|
+
- Gemfile
|
59
|
+
- Gemfile.lock
|
60
|
+
- LICENSE.txt
|
61
|
+
- README.md
|
62
|
+
- Rakefile
|
63
|
+
- boosted.gemspec
|
64
|
+
- lib/boosted.rb
|
65
|
+
- lib/boosted/controllers/filterable.rb
|
66
|
+
- lib/boosted/controllers/pageable.rb
|
67
|
+
- lib/boosted/controllers/searchable.rb
|
68
|
+
- lib/boosted/controllers/sortable.rb
|
69
|
+
- lib/boosted/controllers/tabulatable.rb
|
70
|
+
- lib/boosted/emails/.keep
|
71
|
+
- lib/boosted/jobs/base.rb
|
72
|
+
- lib/boosted/queries/filter.rb
|
73
|
+
- lib/boosted/queries/paginate.rb
|
74
|
+
- lib/boosted/queries/search.rb
|
75
|
+
- lib/boosted/queries/sort.rb
|
76
|
+
- lib/boosted/railtie.rb
|
77
|
+
- lib/boosted/services/base.rb
|
78
|
+
- lib/boosted/tasks/bosted.rake
|
79
|
+
- lib/boosted/tasks/templates/initializer.rb
|
80
|
+
- lib/boosted/version.rb
|
81
|
+
- sig/boosted.rbs
|
82
|
+
homepage: https://github.com/gogrow-dev/boosted
|
83
|
+
licenses:
|
84
|
+
- MIT
|
85
|
+
metadata:
|
86
|
+
homepage_uri: https://github.com/gogrow-dev/boosted
|
87
|
+
source_code_uri: https://github.com/gogrow-dev/boosted
|
88
|
+
rubygems_mfa_required: 'true'
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 3.1.0
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubygems_version: 3.4.10
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Set of modules to boost your Ruby on Rails development
|
108
|
+
test_files: []
|