snfoil 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+ require 'active_support/core_ext/module/attribute_accessors'
5
+
6
+ module SnFoil
7
+ module Searcher
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ TRUECAST = 'true'
12
+ FALSECAST = 'false'
13
+ end
14
+
15
+ class_methods do
16
+ attr_reader :i_model, :i_setup, :i_filters, :i_search_step
17
+
18
+ def model(klass = nil)
19
+ @i_model = klass
20
+ end
21
+
22
+ def setup(setup_method = nil, &setup_block)
23
+ @i_setup = setup_method || setup_block
24
+ end
25
+
26
+ def filter(method = nil, **options, &block)
27
+ raise ArgumentError, 'filter requires either a method name or a block' if method.nil? && block.nil?
28
+
29
+ (@i_filters ||= []) << {
30
+ method: method,
31
+ block: block,
32
+ if: options[:if],
33
+ unless: options[:unless]
34
+ }
35
+ end
36
+ end
37
+
38
+ def model
39
+ self.class.i_model
40
+ end
41
+
42
+ attr_reader :scope
43
+ def initialize(scope: nil)
44
+ @scope = scope || model.all
45
+ end
46
+
47
+ def search(params = {})
48
+ params = transform_params_booleans(params) # this is required for params coming in from http-like sources
49
+ filtered_scope = filter || scope # start usimg the default scope of the class or the filter method
50
+ filtered_scope = apply_setup(filtered_scope, params)
51
+ apply_filters(filtered_scope, params)
52
+ end
53
+
54
+ def filter; end
55
+
56
+ def setup
57
+ self.class.i_setup
58
+ end
59
+
60
+ def filters
61
+ self.class.i_filters || []
62
+ end
63
+
64
+ private
65
+
66
+ def apply_setup(filtered_scope, params)
67
+ return filtered_scope if setup.nil?
68
+
69
+ if setup.is_a?(Symbol) || setup.is_a?(String)
70
+ send(setup, filtered_scope, params)
71
+ else
72
+ setup.call(filtered_scope, params)
73
+ end
74
+ end
75
+
76
+ def apply_filters(filtered_scope, params)
77
+ filters&.reduce(filtered_scope) do |i_scope, i_filter|
78
+ apply_filter(i_filter, i_scope, params)
79
+ end
80
+ end
81
+
82
+ def apply_filter(i_filter, filtered_scope, params)
83
+ return filtered_scope unless filter_valid?(i_filter, params)
84
+
85
+ return send(i_filter[:method], filtered_scope, params) if i_filter[:method]
86
+
87
+ i_filter[:block].call(filtered_scope, params)
88
+ end
89
+
90
+ def filter_valid?(i_filter, params)
91
+ return false if !i_filter[:if].nil? && i_filter[:if].call(params) == false
92
+ return false if !i_filter[:unless].nil? && i_filter[:unless].call(params) == true
93
+
94
+ true
95
+ end
96
+
97
+ def transform_params_booleans(params)
98
+ params.map do |key, value|
99
+ value = if value == TRUECAST
100
+ true
101
+ elsif value == FALSECAST
102
+ false
103
+ else
104
+ value
105
+ end
106
+ [key, value]
107
+ end.to_h
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SnFoil
4
+ VERSION = '0.1.0'
5
+ end
data/lib/sn_foil.rb ADDED
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+ require 'active_support/core_ext/module/attribute_accessors'
5
+ require 'sn_foil/context'
6
+ require 'sn_foil/policy'
7
+ require 'sn_foil/searcher'
8
+ require 'sn_foil/version'
9
+
10
+ module SnFoil
11
+ class Error < StandardError; end
12
+
13
+ mattr_accessor :orm, default: 'active_record'
14
+ mattr_writer :logger
15
+
16
+ class << self
17
+ def logger
18
+ @logger ||= Logger.new($stdout).tap do |log|
19
+ log.progname = name
20
+ end
21
+ end
22
+
23
+ def adapter
24
+ return @adapter if @adapter
25
+
26
+ @adapter ||= if orm.instance_of?(String) || orm.instance_of?(Symbol)
27
+ if Object.const_defined?("SnFoil::Adapters::ORMs::#{orm.camelcase}")
28
+ "SnFoil::Adapters::ORMs::#{orm.camelcase}".constantize
29
+ else
30
+ orm.constantize
31
+ end
32
+ else
33
+ orm
34
+ end
35
+ end
36
+
37
+ def configure
38
+ yield self
39
+ end
40
+ end
41
+ end
data/snfoil.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'sn_foil/version'
6
+
7
+ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
8
+ spec.name = 'snfoil'
9
+ spec.version = SnFoil::VERSION
10
+ spec.authors = ['Matthew Howes', 'Danny Murphy']
11
+ spec.email = ['howeszy@gmail.com', 'dmurph24@gmail.com']
12
+ spec.summary = 'A boilerplate gem for providing basic contexts'
13
+ spec.homepage = 'https://github.com/howeszy/snfoil'
14
+ spec.license = 'MIT'
15
+
16
+ # Specify which files should be added to the gem when it is released.
17
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
19
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ end
21
+ spec.bindir = 'exe'
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_dependency 'activesupport', '>= 5.1'
26
+ spec.add_dependency 'logger', '~> 1.0'
27
+ spec.add_dependency 'pundit', '~> 2.0'
28
+
29
+ spec.add_development_dependency 'bundler', '~> 2.0'
30
+ spec.add_development_dependency 'pry-byebug', '~> 3.0'
31
+ spec.add_development_dependency 'rake', '~> 13.0'
32
+ spec.add_development_dependency 'rspec', '~> 3.9'
33
+ spec.add_development_dependency 'rubocop', '~> 0.76.0'
34
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.36.0'
35
+ spec.add_development_dependency 'dry-struct', '~> 1.0'
36
+ end
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: snfoil
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matthew Howes
8
+ - Danny Murphy
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2020-02-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '5.1'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '5.1'
28
+ - !ruby/object:Gem::Dependency
29
+ name: logger
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: pundit
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '2.0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '2.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: bundler
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '2.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '2.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry-byebug
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '3.0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '3.0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rake
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '13.0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '13.0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '3.9'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '3.9'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rubocop
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: 0.76.0
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: 0.76.0
126
+ - !ruby/object:Gem::Dependency
127
+ name: rubocop-rspec
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: 1.36.0
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: 1.36.0
140
+ - !ruby/object:Gem::Dependency
141
+ name: dry-struct
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: '1.0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: '1.0'
154
+ description:
155
+ email:
156
+ - howeszy@gmail.com
157
+ - dmurph24@gmail.com
158
+ executables: []
159
+ extensions: []
160
+ extra_rdoc_files: []
161
+ files:
162
+ - ".gitignore"
163
+ - ".rubocop.yml"
164
+ - ".ruby-version"
165
+ - CODE_OF_CONDUCT.md
166
+ - Gemfile
167
+ - Gemfile.lock
168
+ - LICENSE.txt
169
+ - README.md
170
+ - Rakefile
171
+ - bin/console
172
+ - bin/setup
173
+ - lib/sn_foil.rb
174
+ - lib/sn_foil/adapters/orms/active_record.rb
175
+ - lib/sn_foil/adapters/orms/base_adapter.rb
176
+ - lib/sn_foil/context.rb
177
+ - lib/sn_foil/contexts/build_context_concern.rb
178
+ - lib/sn_foil/contexts/change_context_concern.rb
179
+ - lib/sn_foil/contexts/create_context_concern.rb
180
+ - lib/sn_foil/contexts/destroy_context_concern.rb
181
+ - lib/sn_foil/contexts/index_context_concern.rb
182
+ - lib/sn_foil/contexts/setup_context_concern.rb
183
+ - lib/sn_foil/contexts/show_context_concern.rb
184
+ - lib/sn_foil/contexts/update_context_concern.rb
185
+ - lib/sn_foil/policy.rb
186
+ - lib/sn_foil/searcher.rb
187
+ - lib/sn_foil/version.rb
188
+ - snfoil.gemspec
189
+ homepage: https://github.com/howeszy/snfoil
190
+ licenses:
191
+ - MIT
192
+ metadata: {}
193
+ post_install_message:
194
+ rdoc_options: []
195
+ require_paths:
196
+ - lib
197
+ required_ruby_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ required_rubygems_version: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
207
+ requirements: []
208
+ rubygems_version: 3.0.3
209
+ signing_key:
210
+ specification_version: 4
211
+ summary: A boilerplate gem for providing basic contexts
212
+ test_files: []