wallaby-active_record 0.2.2 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/lib/adapters/wallaby/active_record/cancancan_provider.rb +1 -1
- data/lib/adapters/wallaby/active_record/default_provider.rb +1 -1
- data/lib/adapters/wallaby/active_record/model_decorator/fields_builder/association_builder.rb +6 -4
- data/lib/adapters/wallaby/active_record/model_decorator/fields_builder/polymorphic_builder.rb +3 -2
- data/lib/adapters/wallaby/active_record/model_decorator/fields_builder/sti_builder.rb +17 -13
- data/lib/adapters/wallaby/active_record/model_decorator/fields_builder.rb +3 -2
- data/lib/adapters/wallaby/active_record/model_decorator/title_field_finder.rb +6 -9
- data/lib/adapters/wallaby/active_record/model_decorator.rb +28 -26
- data/lib/adapters/wallaby/active_record/model_finder.rb +23 -25
- data/lib/adapters/wallaby/active_record/model_pagination_provider.rb +5 -13
- data/lib/adapters/wallaby/active_record/model_service_provider/permitter.rb +1 -1
- data/lib/adapters/wallaby/active_record/model_service_provider/querier/escaper.rb +14 -0
- data/lib/adapters/wallaby/active_record/model_service_provider/querier/transformer.rb +45 -13
- data/lib/adapters/wallaby/active_record/model_service_provider/querier/wrapper.rb +8 -6
- data/lib/adapters/wallaby/active_record/model_service_provider/querier.rb +3 -3
- data/lib/adapters/wallaby/active_record/model_service_provider/validator.rb +6 -4
- data/lib/adapters/wallaby/active_record/model_service_provider.rb +8 -17
- data/lib/adapters/wallaby/active_record/pundit_provider.rb +2 -2
- data/lib/adapters/wallaby/active_record.rb +2 -1
- data/lib/wallaby/active_record/version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55cc61191c3d68eabf0bb98b4977d10c7d5063736e95cba4b4cb446bf1ecebb7
|
4
|
+
data.tar.gz: 8d03e8a115f52bd386e87bd6ba2a8a95fdec39743a1a040396f8f1b06ac1c0fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0685f26c6acf1c511be09cfe68258bce7ca3cd01263047205fcdbfc2e81da7ca1239af3f0725510401d02f6a2c2629003e79a41760a8e672acaa710cd566d8db'
|
7
|
+
data.tar.gz: fa1497666790dba1d421f1194ce3e3ffc4851e3425a7a2da5701af9f5d4573d1df9bbf3a9ee656aa3490f81ed363af4a6758121d6c3cbd761f3d52707f84f6bb
|
data/README.md
CHANGED
@@ -7,7 +7,8 @@
|
|
7
7
|
[![Test Coverage](https://api.codeclimate.com/v1/badges/9ba0a610043a2e1a9e74/test_coverage)](https://codeclimate.com/github/wallaby-rails/wallaby-active_record/test_coverage)
|
8
8
|
[![Inch CI](https://inch-ci.org/github/wallaby-rails/wallaby-active_record.svg?branch=master)](https://inch-ci.org/github/wallaby-rails/wallaby-active_record)
|
9
9
|
|
10
|
-
Wallaby::ActiveRecord is the ActiveRecord adapter
|
10
|
+
Wallaby::ActiveRecord is the ActiveRecord adapter that implements the [Wallaby::Core](https://github.com/wallaby-rails/wallaby-core)
|
11
|
+
interfaces to handle ActiveRecord model/instance(s) in all the CRUD/authorization/pagination operations.
|
11
12
|
|
12
13
|
## Install
|
13
14
|
|
data/lib/adapters/wallaby/active_record/model_decorator/fields_builder/association_builder.rb
CHANGED
@@ -4,7 +4,7 @@ module Wallaby
|
|
4
4
|
class ActiveRecord
|
5
5
|
class ModelDecorator
|
6
6
|
class FieldsBuilder
|
7
|
-
# To build the metadata for associations
|
7
|
+
# To build the metadata for associations fields
|
8
8
|
class AssociationBuilder
|
9
9
|
# Update the metadata
|
10
10
|
# @param metadata [Hash]
|
@@ -18,7 +18,7 @@ module Wallaby
|
|
18
18
|
metadata[:foreign_key] = foreign_key_for(reflection, type)
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
protected
|
22
22
|
|
23
23
|
# @param reflection [ActiveRecord::Reflection]
|
24
24
|
# @param type [Symbol]
|
@@ -35,13 +35,15 @@ module Wallaby
|
|
35
35
|
end
|
36
36
|
|
37
37
|
# @param reflection [ActiveRecord::Reflection]
|
38
|
-
# @return [
|
38
|
+
# @return [true] if it's a through relation
|
39
|
+
# @return [false] otherwise
|
39
40
|
def through?(reflection)
|
40
41
|
reflection.is_a? ::ActiveRecord::Reflection::ThroughReflection
|
41
42
|
end
|
42
43
|
|
43
44
|
# @param reflection [ActiveRecord::Reflection]
|
44
|
-
# @return [
|
45
|
+
# @return [true] if it has scope
|
46
|
+
# @return [false] otherwise
|
45
47
|
def scope?(reflection)
|
46
48
|
reflection.scope.present?
|
47
49
|
end
|
data/lib/adapters/wallaby/active_record/model_decorator/fields_builder/polymorphic_builder.rb
CHANGED
@@ -19,7 +19,7 @@ module Wallaby
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
protected
|
23
23
|
|
24
24
|
# @param reflection [ActiveRecord::Reflection]
|
25
25
|
# @return [Array<Class>] a list of classes for this polymorphism
|
@@ -38,7 +38,8 @@ module Wallaby
|
|
38
38
|
|
39
39
|
# @param model_class [Class]
|
40
40
|
# @param polymorphic_name [String] polymorphic name
|
41
|
-
# @return [
|
41
|
+
# @return [true] if polymorphism defined?
|
42
|
+
# @return [false] otherwise
|
42
43
|
def polymorphic_defined?(model_class, polymorphic_name)
|
43
44
|
polymorphic_name_sym = polymorphic_name.try(:to_sym)
|
44
45
|
model_class.reflections.any? do |_field_name, reflection|
|
@@ -4,44 +4,48 @@ module Wallaby
|
|
4
4
|
class ActiveRecord
|
5
5
|
class ModelDecorator
|
6
6
|
class FieldsBuilder
|
7
|
-
#
|
7
|
+
# This class updates the field metadata's value of **type** and **sti_class_list**
|
8
|
+
# for STI (Single Table Inheritance) model
|
8
9
|
class StiBuilder
|
9
10
|
# @param model_class [Class]
|
10
11
|
def initialize(model_class)
|
11
12
|
@model_class = model_class
|
12
13
|
end
|
13
14
|
|
14
|
-
#
|
15
|
+
# Update the field metadata's value for **type** and **sti_class_list**
|
15
16
|
# @param metadata [Hash]
|
16
17
|
# @param column [ActiveRecord::ConnectionAdapters::Column]
|
17
18
|
def update(metadata, column)
|
18
19
|
return unless @model_class.inheritance_column == column.name
|
19
20
|
|
20
21
|
metadata[:type] = 'sti'
|
21
|
-
metadata[:sti_class_list] = sti_list(
|
22
|
+
metadata[:sti_class_list] = sti_list(find_sti_parent_of(@model_class))
|
22
23
|
end
|
23
24
|
|
24
|
-
|
25
|
+
protected
|
25
26
|
|
27
|
+
# Return the alphabet-order STI list
|
28
|
+
# by traversing the inheritance tree for given model.
|
26
29
|
# @param klass [Class]
|
27
|
-
# @return [Array<Class>]
|
30
|
+
# @return [Array<Class>]
|
28
31
|
def sti_list(klass)
|
29
|
-
|
30
|
-
list.sort_by(&:name)
|
32
|
+
(klass.descendants << klass).sort_by(&:name)
|
31
33
|
end
|
32
34
|
|
35
|
+
# Find out which parent is the one that can give us the STI list.
|
33
36
|
# @param klass [Class]
|
34
|
-
# @return [Class]
|
35
|
-
def
|
37
|
+
# @return [Class]
|
38
|
+
def find_sti_parent_of(klass)
|
36
39
|
parent = klass
|
37
|
-
parent = parent.superclass until
|
40
|
+
parent = parent.superclass until not_sti_parent?(parent.superclass)
|
38
41
|
parent
|
39
42
|
end
|
40
43
|
|
41
44
|
# @param klass [Class]
|
42
|
-
# @return [
|
43
|
-
|
44
|
-
|
45
|
+
# @return [true] if klass is ActiveRecord::Base or abstract
|
46
|
+
# @return [false] otherwise
|
47
|
+
def not_sti_parent?(klass)
|
48
|
+
klass == ::ActiveRecord::Base || klass.try(:abstract_class?)
|
45
49
|
end
|
46
50
|
end
|
47
51
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Wallaby
|
4
4
|
class ActiveRecord
|
5
5
|
class ModelDecorator
|
6
|
-
# To
|
6
|
+
# To build the metadata for fields
|
7
7
|
class FieldsBuilder
|
8
8
|
# @param model_class [Class]
|
9
9
|
def initialize(model_class)
|
@@ -22,7 +22,8 @@ module Wallaby
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
# @return [Hash<String, Hash>] a hash for
|
25
|
+
# @return [Hash<String, Hash>] a hash for association fields
|
26
|
+
# (e.g. belongs_to / has_one / has_many / has_and_belongs_to_many)
|
26
27
|
def association_fields
|
27
28
|
@model_class.reflections.each_with_object({}) do |(name, ref), fields|
|
28
29
|
metadata = {
|
@@ -16,15 +16,12 @@ module Wallaby
|
|
16
16
|
|
17
17
|
# @return [String] field name that can be used as title
|
18
18
|
def find
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
target_field \
|
26
|
-
|| possible_title_fields.keys.first \
|
27
|
-
|| @model_class.primary_key
|
19
|
+
FieldUtils.first_field_by(
|
20
|
+
{
|
21
|
+
name: /title|name|label|string/,
|
22
|
+
type: 'string'
|
23
|
+
}, @fields
|
24
|
+
) || @model_class.primary_key
|
28
25
|
end
|
29
26
|
end
|
30
27
|
end
|
@@ -2,24 +2,25 @@
|
|
2
2
|
|
3
3
|
module Wallaby
|
4
4
|
class ActiveRecord
|
5
|
-
# Modal decorator for ActiveRecord
|
5
|
+
# Modal decorator for {Wallaby::ActiveRecord}
|
6
6
|
class ModelDecorator < ::Wallaby::ModelDecorator
|
7
|
-
# Data types to exclude for
|
8
|
-
INDEX_EXCLUSIVE_DATA_TYPES =
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
# Data types to exclude for {#index_field_names}
|
8
|
+
INDEX_EXCLUSIVE_DATA_TYPES = %w(
|
9
|
+
binary citext hstore json jsonb tsvector xml
|
10
|
+
blob mediumblob longblob text mediumtext longtext
|
11
|
+
).freeze
|
12
12
|
|
13
|
-
#
|
13
|
+
# Classes to exclude for {#show_field_names}
|
14
14
|
SHOW_EXCLUSIVE_CLASS_NAMES = %w(ActiveStorage::Attachment ActiveStorage::Blob).freeze
|
15
15
|
|
16
|
-
#
|
16
|
+
# Fields to exclude for {#form_field_names}
|
17
17
|
FORM_EXCLUSIVE_DATA_TYPES = %w(created_at updated_at).freeze
|
18
18
|
|
19
|
-
#
|
19
|
+
# Original metadata information of the primative and association fields
|
20
|
+
# pulling out from the ActiveRecord model.
|
20
21
|
#
|
21
|
-
# It needs to be frozen so that we can keep the metadata
|
22
|
-
# @example sample fields:
|
22
|
+
# It needs to be frozen so that we can keep the metadata intact.
|
23
|
+
# @example sample fields metadata:
|
23
24
|
# model_decorator.fields
|
24
25
|
# # =>
|
25
26
|
# {
|
@@ -27,28 +28,29 @@ module Wallaby
|
|
27
28
|
# id: { name: 'id', type: 'integer', label: 'Id' },
|
28
29
|
# # association field
|
29
30
|
# category: {
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
31
|
+
# name: 'category',
|
32
|
+
# type: 'belongs_to',
|
33
|
+
# label: 'Category',
|
34
|
+
# is_association: true,
|
35
|
+
# is_through: false,
|
36
|
+
# has_scope: false,
|
37
|
+
# foreign_key: 'category_id',
|
38
|
+
# class: Category
|
38
39
|
# }
|
39
40
|
# }
|
40
41
|
# @return [ActiveSupport::HashWithIndifferentAccess] metadata
|
41
42
|
def fields
|
43
|
+
# NOTE: Need to check the database and table's existence before building up the metadata
|
44
|
+
# so that the database creation and migration related task can be executed.
|
42
45
|
@fields ||= ::ActiveSupport::HashWithIndifferentAccess.new.tap do |hash|
|
43
|
-
|
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?
|
46
|
+
next hash.default = {} unless @model_class.table_exists?
|
47
47
|
|
48
48
|
hash.merge! general_fields
|
49
49
|
hash.merge! association_fields
|
50
50
|
hash.except!(*foreign_keys_from_associations)
|
51
51
|
end.freeze
|
52
|
+
rescue ::ActiveRecord::NoDatabaseError
|
53
|
+
Hash.new({}).with_indifferent_access
|
52
54
|
end
|
53
55
|
|
54
56
|
# A copy of {#fields} for index page
|
@@ -86,7 +88,8 @@ module Wallaby
|
|
86
88
|
end.keys
|
87
89
|
end
|
88
90
|
|
89
|
-
# @return [Array<String>] a list of field names for form (new/edit) page
|
91
|
+
# @return [Array<String>] a list of field names for form (new/edit) page
|
92
|
+
# (note: timestamps fields (e.g. created_at/updated_at) and complex relation fields are excluded).
|
90
93
|
def form_field_names
|
91
94
|
@form_field_names ||=
|
92
95
|
form_fields.reject do |field_name, metadata|
|
@@ -109,9 +112,8 @@ module Wallaby
|
|
109
112
|
# To guess the title for resource.
|
110
113
|
#
|
111
114
|
# It will go through the fields and try to find out the one that looks
|
112
|
-
# like a name or text
|
115
|
+
# like a name or text representing this resource. Otherwise, it will fall
|
113
116
|
# back to primary key.
|
114
|
-
#
|
115
117
|
# @param resource [Object]
|
116
118
|
# @return [String] the title of given resource
|
117
119
|
def guess_title(resource)
|
@@ -2,43 +2,41 @@
|
|
2
2
|
|
3
3
|
module Wallaby
|
4
4
|
class ActiveRecord
|
5
|
-
#
|
5
|
+
# Finder to return all the appropriate ActiveRecord models.
|
6
6
|
class ModelFinder < ::Wallaby::ModelFinder
|
7
|
-
#
|
7
|
+
# Return a list of ActiveRecord::Base subclasses that aren't one of the following types:
|
8
|
+
#
|
9
|
+
# 1. abstract class
|
10
|
+
# 2. anonymous class
|
11
|
+
# 3. the HABTM relation class
|
12
|
+
# @return [Array<Class>]
|
8
13
|
def all
|
9
|
-
|
10
|
-
|
14
|
+
::ActiveRecord::Base.descendants.reject do |model_class|
|
15
|
+
defined?(::ApplicationRecord) && model_class == ::ApplicationRecord ||
|
16
|
+
model_class.abstract_class? ||
|
17
|
+
anonymous?(model_class) ||
|
18
|
+
model_class.name.index('HABTM') ||
|
19
|
+
invalid_class_name?(model_class)
|
11
20
|
end.sort_by(&:to_s)
|
12
21
|
end
|
13
22
|
|
14
|
-
|
15
|
-
# @return [ApplicationRecord, ActiveRecord::Base] base ActiveRecord class
|
16
|
-
def self.base
|
17
|
-
return ::ApplicationRecord if defined? ::ApplicationRecord
|
23
|
+
protected
|
18
24
|
|
19
|
-
::ActiveRecord::Base
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
# Is model class abstract?
|
25
25
|
# @param model_class [Class]
|
26
|
-
# @return [Boolean]
|
27
|
-
def abstract?(model_class)
|
28
|
-
model_class.abstract_class?
|
29
|
-
end
|
30
|
-
|
31
26
|
# @see Wallaby::ModuleUtils.anonymous_class?
|
32
27
|
def anonymous?(model_class)
|
33
|
-
ModuleUtils.anonymous_class?
|
28
|
+
ModuleUtils.anonymous_class?(model_class).tap do |result|
|
29
|
+
Logger.warn "Anonymous class is detected for table #{model_class.try :table_name}" if result
|
30
|
+
end
|
34
31
|
end
|
35
32
|
|
36
|
-
#
|
37
|
-
# for has and belongs to many assocation
|
33
|
+
# To exclude classes that have invalid class name, e.g. **primary::SchemaMigration** from Rails test
|
38
34
|
# @param model_class [Class]
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
def invalid_class_name?(model_class)
|
36
|
+
model_class.name.constantize
|
37
|
+
false
|
38
|
+
rescue NameError
|
39
|
+
true
|
42
40
|
end
|
43
41
|
end
|
44
42
|
end
|
@@ -8,25 +8,17 @@ module Wallaby
|
|
8
8
|
# @return [true] if paginatable
|
9
9
|
# @return [false] if not paginatable
|
10
10
|
def paginatable?
|
11
|
-
paginatable
|
12
|
-
#
|
13
|
-
|
14
|
-
@collection.respond_to?(:total_entries) # will_paginate
|
15
|
-
Rails.logger.warn "#{@collection.inspect} is not paginatable.\nfrom #{__FILE__}:#{__LINE__}" unless paginatable
|
16
|
-
|
17
|
-
paginatable
|
11
|
+
(@collection.respond_to?(:unscope) && @collection.respond_to?(:count)).tap do |paginatable|
|
12
|
+
Logger.warn "#{@collection} is not paginatable." unless paginatable
|
13
|
+
end
|
18
14
|
end
|
19
15
|
|
20
16
|
# @return [Integer] total count for the collection
|
21
17
|
def total
|
22
|
-
|
23
|
-
@collection.try(:total_count) || \
|
24
|
-
@collection.try(:total_entries) # will_paginate
|
18
|
+
@collection.unscope(:offset, :limit).count
|
25
19
|
end
|
26
20
|
|
27
|
-
# @return [Integer] page size from parameters or
|
28
|
-
# {https://rubydoc.info/gems/wallaby-core/Wallaby/Configuration/Pagination#page_size-instance_method page_size}
|
29
|
-
# Wallaby configuration
|
21
|
+
# @return [Integer] page size from parameters or Wallaby configuration
|
30
22
|
def page_size
|
31
23
|
(@params[:per] || Wallaby.configuration.pagination.page_size).to_i
|
32
24
|
end
|
@@ -11,6 +11,14 @@ module Wallaby
|
|
11
11
|
PCT = '%' # :nodoc:
|
12
12
|
|
13
13
|
class << self
|
14
|
+
# @example Return the escaped keyword if the first/last char of the keyword is `%`/`_`
|
15
|
+
# Wallaby::ActiveRecord::ModelServiceProvider::Querier::Escaper.execute('%something_else%')
|
16
|
+
# # => '%something\_else%'
|
17
|
+
# @example Return the escaped keyword wrapped with `%` if the first/last char of the keyword is NOT `%`/`_`
|
18
|
+
# Wallaby::ActiveRecord::ModelServiceProvider::Querier::Escaper.execute('keyword')
|
19
|
+
# # => '%keyword%'
|
20
|
+
# @param keyword [String]
|
21
|
+
# @return [String] escaped string for LIKE query
|
14
22
|
def execute(keyword)
|
15
23
|
first = keyword.first
|
16
24
|
last = keyword.last
|
@@ -23,6 +31,12 @@ module Wallaby
|
|
23
31
|
"#{starting}#{escaped}#{ending}"
|
24
32
|
end
|
25
33
|
|
34
|
+
protected
|
35
|
+
|
36
|
+
# @param first_condition [Boolean] first condition
|
37
|
+
# @param first_char [Boolean] first char
|
38
|
+
# @param second_condition [nil, String] second condition
|
39
|
+
# @param default_sign [String]
|
26
40
|
def sign(
|
27
41
|
first_condition, first_char, second_condition, default_sign = PCT
|
28
42
|
)
|
@@ -34,9 +34,21 @@ module Wallaby
|
|
34
34
|
':!()' => :not_between
|
35
35
|
}.freeze
|
36
36
|
|
37
|
+
SEQUENCE_JOIN_OPERATORS = { # :nodoc:
|
38
|
+
':' => :or,
|
39
|
+
':=' => :or,
|
40
|
+
':!' => :and,
|
41
|
+
':!=' => :and,
|
42
|
+
':<>' => :and
|
43
|
+
}.freeze
|
44
|
+
|
45
|
+
BETWEEN_OPERATORS = { # :nodoc:
|
46
|
+
':()' => true,
|
47
|
+
':!()' => true
|
48
|
+
}.freeze
|
49
|
+
|
37
50
|
# For single null
|
38
51
|
rule null: simple(:value)
|
39
|
-
rule null: sequence(:value)
|
40
52
|
|
41
53
|
# For single boolean
|
42
54
|
rule(boolean: simple(:value)) { /true/i.match? value }
|
@@ -51,8 +63,7 @@ module Wallaby
|
|
51
63
|
rule left: simple(:left), op: simple(:op), right: simple(:right) do
|
52
64
|
oped = op.try :to_str
|
53
65
|
operator = SIMPLE_OPERATORS[oped]
|
54
|
-
#
|
55
|
-
next unless operator
|
66
|
+
next Transformer.warn "Unknown operator #{oped} for %<exp>s", instance_values unless operator
|
56
67
|
|
57
68
|
lefted = left.try :to_str
|
58
69
|
convert =
|
@@ -68,24 +79,45 @@ module Wallaby
|
|
68
79
|
rule left: simple(:left), op: simple(:op), right: sequence(:right) do
|
69
80
|
oped = op.try :to_str
|
70
81
|
operator = SEQUENCE_OPERATORS[oped]
|
71
|
-
next unless operator
|
82
|
+
next Transformer.warn "Unknown operator #{oped} for %<exp>s", instance_values unless operator
|
72
83
|
|
73
84
|
exps = Wrapper.new
|
74
85
|
lefted = left.try :to_str
|
75
|
-
if
|
76
|
-
|
77
|
-
next unless nil_operator
|
86
|
+
if BETWEEN_OPERATORS[oped] # BETWEEN related operators
|
87
|
+
next Transformer.warn 'Invalid values for %<exp>s', instance_values unless right.first && right.second
|
78
88
|
|
79
|
-
|
89
|
+
convert = Range.new right.first, right.second
|
90
|
+
exps.push left: lefted, op: operator, right: convert
|
91
|
+
else
|
92
|
+
join = SEQUENCE_JOIN_OPERATORS[oped]
|
93
|
+
if right.include? nil
|
94
|
+
exps.push left: lefted, op: SIMPLE_OPERATORS[oped], right: right.delete(nil), join: join
|
95
|
+
end
|
96
|
+
exps.push left: lefted, op: operator, right: right, join: join
|
80
97
|
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
98
|
exps
|
84
99
|
end
|
85
100
|
|
86
|
-
|
87
|
-
|
88
|
-
|
101
|
+
class << self
|
102
|
+
# @param query_string [String]
|
103
|
+
# @return [Array]
|
104
|
+
def execute(query_string)
|
105
|
+
result = new.apply Parser.new.parse(query_string || EMPTY_STRING)
|
106
|
+
result.is_a?(Array) ? result : [result]
|
107
|
+
end
|
108
|
+
|
109
|
+
# @param message [String]
|
110
|
+
# @param exp [Hash,nil] transformed expression
|
111
|
+
# @return [nil]
|
112
|
+
def warn(message, exp = nil)
|
113
|
+
Logger.warn message, exp: to_origin(exp), sourcing: 2
|
114
|
+
end
|
115
|
+
|
116
|
+
# @param exp [Hash,nil] transformed expression
|
117
|
+
# @return [String] origin expression
|
118
|
+
def to_origin(exp)
|
119
|
+
"'#{exp['left']}#{exp['op']}#{exp['right']}'"
|
120
|
+
end
|
89
121
|
end
|
90
122
|
end
|
91
123
|
end
|
@@ -4,18 +4,20 @@ module Wallaby
|
|
4
4
|
class ActiveRecord
|
5
5
|
class ModelServiceProvider
|
6
6
|
class Querier
|
7
|
-
#
|
7
|
+
# Wrapper for the {Wallaby::ActiveRecord::ModelServiceProvider::Querier::Transformer} result.
|
8
|
+
# It's only used by {Wallaby::ActiveRecord::ModelServiceProvider::Querier} to tell it apart
|
9
|
+
# with non-{Wallaby::ActiveRecord::ModelServiceProvider::Querier::Transformer} result
|
8
10
|
class Wrapper
|
9
11
|
attr_reader :list
|
10
|
-
delegate :push,
|
12
|
+
delegate :push, to: :list
|
13
|
+
delegate :each, to: :list
|
14
|
+
delegate :last, to: :list
|
15
|
+
delegate :[], to: :last
|
11
16
|
|
17
|
+
# @param list [Array]
|
12
18
|
def initialize(list = [])
|
13
19
|
@list = list
|
14
20
|
end
|
15
|
-
|
16
|
-
def [](key)
|
17
|
-
list.last[key]
|
18
|
-
end
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
@@ -26,7 +26,7 @@ module Wallaby
|
|
26
26
|
scope.where query
|
27
27
|
end
|
28
28
|
|
29
|
-
|
29
|
+
protected
|
30
30
|
|
31
31
|
# @return [Arel::Table] arel table
|
32
32
|
def table
|
@@ -36,7 +36,7 @@ module Wallaby
|
|
36
36
|
# @param params [ActionController::Parameters]
|
37
37
|
# @return [Array<String, Array, Array>] filter_name, keywords, field_queries
|
38
38
|
def extract(params)
|
39
|
-
expressions = Transformer.
|
39
|
+
expressions = Transformer.execute params[:q]
|
40
40
|
keywords = expressions.select { |v| v.is_a? String }
|
41
41
|
field_queries = expressions.select { |v| v.is_a? Wrapper }
|
42
42
|
filter_name = params[:filter]
|
@@ -149,7 +149,7 @@ module Wallaby
|
|
149
149
|
query = nil
|
150
150
|
exps.each do |exp|
|
151
151
|
sub = table[exp[:left]].try(exp[:op], exp[:right])
|
152
|
-
query = query.try(:
|
152
|
+
query = query.try(exp[:join], sub) || sub
|
153
153
|
end
|
154
154
|
query
|
155
155
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Wallaby
|
4
4
|
class ActiveRecord
|
5
5
|
class ModelServiceProvider
|
6
|
-
#
|
6
|
+
# Validate values for record create / update
|
7
7
|
class Validator
|
8
8
|
# @param model_decorator [Wallaby::ModelDecorator]
|
9
9
|
def initialize(model_decorator)
|
@@ -11,7 +11,8 @@ module Wallaby
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# @param resource [Object] resource object
|
14
|
-
# @return [
|
14
|
+
# @return [true] if the resource object is valid
|
15
|
+
# @return [false] otherwise
|
15
16
|
def valid?(resource)
|
16
17
|
resource.attributes.each do |field_name, values|
|
17
18
|
metadata = @model_decorator.fields[field_name]
|
@@ -22,10 +23,11 @@ module Wallaby
|
|
22
23
|
resource.errors.blank?
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
+
protected
|
26
27
|
|
27
28
|
# @param values [Array]
|
28
|
-
# @return [
|
29
|
+
# @return [true] if the values are valid range values
|
30
|
+
# @return [false] otherwise
|
29
31
|
def valid_range_type?(values, metadata)
|
30
32
|
!metadata \
|
31
33
|
|| !%w(daterange tsrange tstzrange).include?(metadata[:type]) \
|
@@ -8,7 +8,6 @@ module Wallaby
|
|
8
8
|
# @param action [String, Symbol]
|
9
9
|
# @param authorizer
|
10
10
|
# @return [ActionController::Parameters] whitelisted parameters
|
11
|
-
# @see Wallaby::ModelServiceProvider#permit
|
12
11
|
def permit(params, action, authorizer)
|
13
12
|
authorized_fields = authorizer.permit_params action, @model_class
|
14
13
|
params.require(param_key).permit(authorized_fields || permitted_fields)
|
@@ -18,7 +17,6 @@ module Wallaby
|
|
18
17
|
# @param params [ActionController::Parameters]
|
19
18
|
# @param authorizer [Ability] for now
|
20
19
|
# @return [ActiveRecord::Relation] relation
|
21
|
-
# @see Wallaby::ModelServiceProvider#collection
|
22
20
|
def collection(params, authorizer)
|
23
21
|
query = querier.search params
|
24
22
|
query = query.order params[:sort] if params[:sort].present?
|
@@ -28,19 +26,15 @@ module Wallaby
|
|
28
26
|
# @param query [ActiveRecord::Relation]
|
29
27
|
# @param params [ActionController::Parameters]
|
30
28
|
# @return [ActiveRecord::Relation] paginated query
|
31
|
-
# @see Wallaby::ModelServiceProvider#paginate
|
32
29
|
def paginate(query, params)
|
33
|
-
# NOTE: do not take out the `.to_i` as will_paginate requires an integer `per_page`
|
34
30
|
per = (params[:per] || Wallaby.configuration.pagination.page_size).to_i
|
35
|
-
|
36
|
-
query = query.
|
37
|
-
query = query.per_page per if query.respond_to? :per_page # will_paginate
|
31
|
+
page = [params[:page].to_i, 1].max # starting from page 1
|
32
|
+
query = query.offset((page - 1) * per).limit(per)
|
38
33
|
query
|
39
34
|
end
|
40
35
|
|
41
36
|
# @note No mass assignment happens here!
|
42
37
|
# @return [Object] new resource object
|
43
|
-
# @see Wallaby::ModelServiceProvider#new
|
44
38
|
def new(_params, _authorizer)
|
45
39
|
@model_class.new
|
46
40
|
end
|
@@ -50,7 +44,6 @@ module Wallaby
|
|
50
44
|
# @param id [Integer, String]
|
51
45
|
# @return [Object] persisted resource object
|
52
46
|
# @raise [Wallaby::ResourceNotFound] when record is not found
|
53
|
-
# @see Wallaby::ModelServiceProvider#find
|
54
47
|
def find(id, _params, _authorizer)
|
55
48
|
@model_class.find id
|
56
49
|
rescue ::ActiveRecord::RecordNotFound
|
@@ -61,7 +54,6 @@ module Wallaby
|
|
61
54
|
# @param resource [Object]
|
62
55
|
# @param params [ActionController::Parameters]
|
63
56
|
# @param authorizer [Wallaby::ModelAuthorizer]
|
64
|
-
# @see Wallaby::ModelServiceProvider#create
|
65
57
|
def create(resource, params, authorizer)
|
66
58
|
save __callee__, resource, params, authorizer
|
67
59
|
end
|
@@ -70,14 +62,12 @@ module Wallaby
|
|
70
62
|
# @param resource [Object]
|
71
63
|
# @param params [ActionController::Parameters]
|
72
64
|
# @param authorizer [Wallaby::ModelAuthorizer]
|
73
|
-
# @see Wallaby::ModelServiceProvider#update
|
74
65
|
def update(resource, params, authorizer)
|
75
66
|
save __callee__, resource, params, authorizer
|
76
67
|
end
|
77
68
|
|
78
69
|
# Remove a record from database
|
79
70
|
# @param resource [Object]
|
80
|
-
# @see Wallaby::ModelServiceProvider#destroy
|
81
71
|
def destroy(resource, _params, _authorizer)
|
82
72
|
resource.destroy
|
83
73
|
end
|
@@ -109,7 +99,8 @@ module Wallaby
|
|
109
99
|
|
110
100
|
# See if a resource is valid
|
111
101
|
# @param resource [Object]
|
112
|
-
# @return [
|
102
|
+
# @return [true] if valid
|
103
|
+
# @return [false] otherwise
|
113
104
|
def valid?(resource)
|
114
105
|
validator.valid? resource
|
115
106
|
end
|
@@ -137,22 +128,22 @@ module Wallaby
|
|
137
128
|
permitter.simple_field_names << permitter.compound_hashed_fields
|
138
129
|
end
|
139
130
|
|
140
|
-
# @
|
131
|
+
# @return [Wallaby::ActiveRecord::ModelServiceProvider::Permitter]
|
141
132
|
def permitter
|
142
133
|
@permitter ||= Permitter.new @model_decorator
|
143
134
|
end
|
144
135
|
|
145
|
-
# @
|
136
|
+
# @return [Wallaby::ActiveRecord::ModelServiceProvider::Querier]
|
146
137
|
def querier
|
147
138
|
@querier ||= Querier.new @model_decorator
|
148
139
|
end
|
149
140
|
|
150
|
-
# @
|
141
|
+
# @return [Wallaby::ActiveRecord::ModelServiceProvider::Normalizer]
|
151
142
|
def normalizer
|
152
143
|
@normalizer ||= Normalizer.new @model_decorator
|
153
144
|
end
|
154
145
|
|
155
|
-
# @
|
146
|
+
# @return [Wallaby::ActiveRecord::ModelServiceProvider::Validator]
|
156
147
|
def validator
|
157
148
|
@validator ||= Validator.new @model_decorator
|
158
149
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Wallaby
|
4
4
|
class ActiveRecord
|
5
|
-
# Pundit provider for ActiveRecord
|
5
|
+
# Pundit provider for {Wallaby::ActiveRecord}
|
6
6
|
class PunditProvider < PunditAuthorizationProvider
|
7
7
|
# Filter a scope
|
8
8
|
# @param _action [Symbol, String]
|
@@ -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
|
-
|
14
|
+
Logger.warn "Cannot find scope policy for `#{scope}`."
|
15
15
|
scope
|
16
16
|
end
|
17
17
|
end
|
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.
|
4
|
+
version: 0.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tian Chen
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.2.
|
33
|
+
version: 0.2.3
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.2.
|
40
|
+
version: 0.2.3
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: cancancan
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,7 +132,7 @@ metadata:
|
|
132
132
|
homepage_uri: https://github.com/wallaby-rails/wallaby-active_record
|
133
133
|
source_code_uri: https://github.com/wallaby-rails/wallaby-active_record
|
134
134
|
changelog_uri: https://github.com/wallaby-rails/wallaby-active_record/blob/master/CHANGELOG.md
|
135
|
-
post_install_message:
|
135
|
+
post_install_message:
|
136
136
|
rdoc_options: []
|
137
137
|
require_paths:
|
138
138
|
- lib
|
@@ -147,8 +147,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
147
|
- !ruby/object:Gem::Version
|
148
148
|
version: '0'
|
149
149
|
requirements: []
|
150
|
-
rubygems_version: 3.
|
151
|
-
signing_key:
|
150
|
+
rubygems_version: 3.1.2
|
151
|
+
signing_key:
|
152
152
|
specification_version: 4
|
153
153
|
summary: Wallaby's ActiveRecord ORM adapter
|
154
154
|
test_files: []
|