wallaby-active_record 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d10a3ddeced877f4c004c1d2a5141b6463865a22d673ae91a9ca87a22a3523c
4
- data.tar.gz: c194bdfef64070a23a5bc0ebdf7d0bdbc327047eb330a459e81b616fd5ab6f84
3
+ metadata.gz: 93579d0cc4c2a81356d19acc3a24a7cac7160406f4c09c829de95f10d3db1020
4
+ data.tar.gz: d591a516f5c2fc04d7b6f46af992498e093d5d3f706d03c639a77a11eeeba339
5
5
  SHA512:
6
- metadata.gz: '0695f8352480c7597eae7e5049e8d009ae3f30afa4400c233bd4f036a42abab71780cfe7b62f5c362f21b0a31384dee564655de5fbd76628fd282714eb6f2b8d'
7
- data.tar.gz: 3c34d83727141ee696e9f839f78ac209fabec0edd1437265f013f23f0ff6531dcba8aa762038cc4487c11a3b599ead2520f0f0b3e46e80b3e0184febf9cd267a
6
+ metadata.gz: 9197ae20142ea0190ed68314ef6eb5c7ec4915febe072f62f0144bb6f42dddbada38adadf05b83eba0ed9744d2c3bc050f2836b25a46c394ab553decaa4f0dee
7
+ data.tar.gz: 0a59dcd809acb177822b3665b576b18eefdb0ef55b4fdcfdc6a3cf9344ce73fa1ddc4cb608c47de4d630b6149d0f1a36569eee8c63253830ddad92aae3c3f514
@@ -40,14 +40,14 @@ module Wallaby
40
40
  # @return [ActiveSupport::HashWithIndifferentAccess] metadata
41
41
  def fields
42
42
  @fields ||= ::ActiveSupport::HashWithIndifferentAccess.new.tap do |hash|
43
- # NOTE: There is a chance that people create ActiveRecord class
44
- # before they do the migration, so initialising the fields will raise
45
- # all kinds of error. Therefore, we need to check the table existence
46
- if @model_class.table_exists?
47
- hash.merge! general_fields
48
- hash.merge! association_fields
49
- hash.except!(*foreign_keys_from_associations)
50
- end
43
+ # NOTE: Need to check database and table's existence
44
+ # before pulling out the metadata from model.
45
+ # So that the database and migration related task can be executed.
46
+ next unless ::ActiveRecord::Base.connected? && @model_class.table_exists?
47
+
48
+ hash.merge! general_fields
49
+ hash.merge! association_fields
50
+ hash.except!(*foreign_keys_from_associations)
51
51
  end.freeze
52
52
  end
53
53
 
@@ -12,11 +12,7 @@ module Wallaby
12
12
  # kaminari
13
13
  @collection.respond_to?(:total_count) || \
14
14
  @collection.respond_to?(:total_entries) # will_paginate
15
- unless paginatable
16
- Rails.logger.warn I18n.t(
17
- 'errors.activerecord.paginatable', collection: @collection.inspect
18
- )
19
- end
15
+ Rails.logger.warn "#{@collection.inspect} is not paginatable.\nfrom #{__FILE__}:#{__LINE__}" unless paginatable
20
16
 
21
17
  paginatable
22
18
  end
@@ -61,7 +61,7 @@ module Wallaby
61
61
  when ':^', ':!^' then "#{right}%"
62
62
  when ':$', ':!$' then "%#{right}"
63
63
  end
64
- { left: lefted, op: operator, right: convert || right }
64
+ Wrapper.new [{ left: lefted, op: operator, right: convert || right }]
65
65
  end
66
66
 
67
67
  # For operators that have multiple items
@@ -70,9 +70,22 @@ module Wallaby
70
70
  operator = SEQUENCE_OPERATORS[oped]
71
71
  next unless operator
72
72
 
73
+ exps = Wrapper.new
73
74
  lefted = left.try :to_str
74
- convert = Range.new right.try(:first), right.try(:last) if %w(:() :!()).include?(oped)
75
- { left: lefted, op: operator, right: convert || right }
75
+ if right.include? nil
76
+ nil_operator = SIMPLE_OPERATORS[oped]
77
+ next unless nil_operator
78
+
79
+ exps.push left: lefted, op: nil_operator, right: right.delete(nil)
80
+ end
81
+ convert = Range.new right.try(:first), right.try(:second) if %w(:() :!()).include?(oped)
82
+ exps.push left: lefted, op: operator, right: convert || right
83
+ exps
84
+ end
85
+
86
+ def transform(query_string)
87
+ result = apply Parser.new.parse(query_string || EMPTY_STRING)
88
+ result.is_a?(Array) ? result : [result]
76
89
  end
77
90
  end
78
91
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ class ActiveRecord
5
+ class ModelServiceProvider
6
+ class Querier
7
+ # Build up query using the results
8
+ class Wrapper
9
+ attr_reader :list
10
+ delegate :push, :each, to: :list
11
+
12
+ def initialize(list = [])
13
+ @list = list
14
+ end
15
+
16
+ def [](key)
17
+ list.last[key]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -13,9 +13,9 @@ module Wallaby
13
13
  @model_class = @model_decorator.model_class
14
14
  end
15
15
 
16
- # Pull out the query expression string from the parameter `q`,
17
- # use parser to understand the expression, then use transformer to run
18
- # SQL arel query.
16
+ # Extract the filter and query information
17
+ # from parameters `filter` and `q` respectively,
18
+ # and execute query based on the information.
19
19
  # @param params [ActionController::Parameters]
20
20
  # @return [ActiveRecord::Relation]
21
21
  def search(params)
@@ -28,40 +28,21 @@ module Wallaby
28
28
 
29
29
  private
30
30
 
31
- # @see Wallaby::Parser
32
- def parser
33
- @parser ||= Parser.new
34
- end
35
-
36
- # @see Wallaby::ActiveRecord::ModelServiceProvider::Querier::Transformer
37
- def transformer
38
- @transformer ||= Transformer.new
39
- end
40
-
41
31
  # @return [Arel::Table] arel table
42
32
  def table
43
33
  @model_class.arel_table
44
34
  end
45
35
 
46
36
  # @param params [ActionController::Parameters]
47
- # @return [Array<String, Array, Array>] a list of object for other
48
- # method to use.
37
+ # @return [Array<String, Array, Array>] filter_name, keywords, field_queries
49
38
  def extract(params)
50
- expressions = to_expressions params
39
+ expressions = Transformer.new.transform params[:q]
51
40
  keywords = expressions.select { |v| v.is_a? String }
52
- field_queries = expressions.select { |v| v.is_a? Hash }
41
+ field_queries = expressions.select { |v| v.is_a? Wrapper }
53
42
  filter_name = params[:filter]
54
43
  [filter_name, keywords, field_queries]
55
44
  end
56
45
 
57
- # @param params [ActionController::Parameters]
58
- # @return [Array] a list of transformed operations
59
- def to_expressions(params)
60
- parsed = parser.parse(params[:q] || EMPTY_STRING)
61
- converted = transformer.apply parsed
62
- converted.is_a?(Array) ? converted : [converted]
63
- end
64
-
65
46
  # Use the filter name to find out the scope in the following precedents:
66
47
  # - scope from metadata
67
48
  # - defined scope from the model
@@ -81,25 +62,23 @@ module Wallaby
81
62
  end
82
63
 
83
64
  # Find out the scope for given filter
84
- # - from metadata
65
+ # - from filter metadata
85
66
  # - filter name itself
86
67
  # @param filter_name [String] filter name
87
68
  # @return [String]
88
69
  def find_scope(filter_name)
89
- filter = @model_decorator.filters[filter_name] || {}
90
- filter[:scope] || filter_name
70
+ @model_decorator.filters[filter_name].try(:[], :scope) || filter_name
91
71
  end
92
72
 
93
- # Unscoped query
94
- # @return [ActiveRecord::Relation]
73
+ # @return [ActiveRecord::Relation] Unscoped query
95
74
  def unscoped
96
75
  @model_class.where nil
97
76
  end
98
77
 
99
- # Search text for the text columns that appear in `index_field_names`
78
+ # Search text for the text columns (see {}) in `index_field_names`
100
79
  # @param keywords [String] keywords
101
80
  # @param query [ActiveRecord::Relation, nil]
102
- # @return [ActiveRecord::Relation]
81
+ # @return [ActiveRecord::Relation, nil]
103
82
  def text_search(keywords, query = nil)
104
83
  return query unless keywords_check? keywords
105
84
 
@@ -121,9 +100,9 @@ module Wallaby
121
100
  def field_search(field_queries, query)
122
101
  return query unless field_check? field_queries
123
102
 
124
- field_queries.each do |exp|
125
- sub_query = table[exp[:left]].try(exp[:op], exp[:right])
126
- query = query.try(:and, sub_query) || sub_query
103
+ field_queries.each do |exps|
104
+ sub_queries = build_sub_queries_with exps
105
+ query = query.try(:and, sub_queries) || sub_queries
127
106
  end
128
107
  query
129
108
  end
@@ -140,21 +119,20 @@ module Wallaby
140
119
  end
141
120
 
142
121
  # @param keywords [Array<String>] a list of keywords
143
- # @return [Boolean] false when keywords are empty
144
- # true when text fields for query exist
145
- # otherwise, raise exception
122
+ # @return [false] when keywords are empty
123
+ # @return [true] when text fields for query exist
124
+ # @raise [Wallaby::UnprocessableEntity] if no text columns can be used for text search
146
125
  def keywords_check?(keywords)
147
126
  return false if keywords.blank?
148
127
  return true if text_fields.present?
149
128
 
150
- message = I18n.t 'errors.unprocessable_entity.keyword_search'
151
- raise UnprocessableEntity, message
129
+ raise UnprocessableEntity, 'Unable to perform keyword search when no text fields can be used for this.'
152
130
  end
153
131
 
154
132
  # @param field_queries [Array]
155
- # @return [Boolean] false when field queries are blank
156
- # true when the fields used are valid (exist in `fields`)
157
- # otherwise, raise exception
133
+ # @return [false] when field queries are blank
134
+ # @return [true] when field queries are blank
135
+ # @raise [Wallaby::UnprocessableEntity] if invalid fields are entered
158
136
  def field_check?(field_queries)
159
137
  return false if field_queries.blank?
160
138
 
@@ -162,9 +140,18 @@ module Wallaby
162
140
  invalid_fields = fields - @model_decorator.fields.keys
163
141
  return true if invalid_fields.blank?
164
142
 
165
- message = I18n.t 'errors.unprocessable_entity.field_colon_search',
166
- invalid_fields: invalid_fields.to_sentence
167
- raise UnprocessableEntity, message
143
+ raise UnprocessableEntity, "Unable to perform field colon search for #{invalid_fields.to_sentence}"
144
+ end
145
+
146
+ # @param exps [Wallaby::ActiveRecord::ModelServiceProvider::Querier::Wrapper]
147
+ # @return [ActiveRecord::Relation] sub queries connected using OR
148
+ def build_sub_queries_with(exps)
149
+ query = nil
150
+ exps.each do |exp|
151
+ sub = table[exp[:left]].try(exp[:op], exp[:right])
152
+ query = query.try(:or, sub) || sub
153
+ end
154
+ query
168
155
  end
169
156
  end
170
157
  end
@@ -11,7 +11,7 @@ module Wallaby
11
11
  def accessible_for(_action, scope)
12
12
  Pundit.policy_scope! user, scope
13
13
  rescue Pundit::NotDefinedError
14
- Rails.logger.warn I18n.t('errors.pundit.not_found.scope_policy', scope: scope)
14
+ Rails.logger.warn "Cannot find scope policy for #{scope.inspect}.\nfrom #{__FILE__}:#{__LINE__}"
15
15
  scope
16
16
  end
17
17
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Wallaby
4
4
  module ActiveRecordGem
5
- VERSION = '0.2.1' # :nodoc:
5
+ VERSION = '0.2.2' # :nodoc:
6
6
  end
7
7
  end
@@ -28,6 +28,7 @@ require 'adapters/wallaby/active_record/model_service_provider/permitter'
28
28
  require 'adapters/wallaby/active_record/model_service_provider/querier'
29
29
  require 'adapters/wallaby/active_record/model_service_provider/querier/escaper'
30
30
  require 'adapters/wallaby/active_record/model_service_provider/querier/transformer'
31
+ require 'adapters/wallaby/active_record/model_service_provider/querier/wrapper'
31
32
  require 'adapters/wallaby/active_record/model_service_provider/validator'
32
33
  # ModelServiceProvider: end
33
34
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wallaby-active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tian Chen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-17 00:00:00.000000000 Z
11
+ date: 2020-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -120,6 +120,7 @@ files:
120
120
  - lib/adapters/wallaby/active_record/model_service_provider/querier.rb
121
121
  - lib/adapters/wallaby/active_record/model_service_provider/querier/escaper.rb
122
122
  - lib/adapters/wallaby/active_record/model_service_provider/querier/transformer.rb
123
+ - lib/adapters/wallaby/active_record/model_service_provider/querier/wrapper.rb
123
124
  - lib/adapters/wallaby/active_record/model_service_provider/validator.rb
124
125
  - lib/adapters/wallaby/active_record/pundit_provider.rb
125
126
  - lib/wallaby/active_record.rb