shamu 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +55 -20
- data/Gemfile +3 -3
- data/Gemfile.lock +13 -11
- data/circle.yml +1 -1
- data/lib/shamu/attributes/assignment.rb +44 -5
- data/lib/shamu/attributes/camel_case.rb +21 -0
- data/lib/shamu/attributes/validation.rb +13 -1
- data/lib/shamu/attributes/validators/valid_validator.rb +14 -0
- data/lib/shamu/attributes/validators.rb +7 -0
- data/lib/shamu/attributes.rb +13 -8
- data/lib/shamu/auditing/auditing_service.rb +1 -5
- data/lib/shamu/auditing/support.rb +14 -2
- data/lib/shamu/entities/active_record.rb +16 -2
- data/lib/shamu/entities/active_record_soft_destroy.rb +7 -3
- data/lib/shamu/entities/entity.rb +1 -1
- data/lib/shamu/entities/entity_lookup_service.rb +137 -0
- data/lib/shamu/entities/entity_path.rb +6 -9
- data/lib/shamu/entities/list.rb +8 -2
- data/lib/shamu/entities/list_scope/paging.rb +3 -3
- data/lib/shamu/entities/list_scope/sorting.rb +21 -2
- data/lib/shamu/entities/list_scope/window_paging.rb +96 -0
- data/lib/shamu/entities/list_scope.rb +2 -2
- data/lib/shamu/entities/opaque_entity_lookup_service.rb +59 -0
- data/lib/shamu/entities/opaque_id.rb +54 -0
- data/lib/shamu/entities/paged_list.rb +137 -0
- data/lib/shamu/entities.rb +5 -1
- data/lib/shamu/events/active_record/service.rb +1 -2
- data/lib/shamu/events/in_memory/service.rb +1 -2
- data/lib/shamu/features/conditions/percentage.rb +3 -3
- data/lib/shamu/features/features_service.rb +2 -2
- data/lib/shamu/features/toggle.rb +2 -3
- data/lib/shamu/json_api/context.rb +0 -1
- data/lib/shamu/json_api/rails/controller.rb +0 -2
- data/lib/shamu/rails/controller.rb +0 -1
- data/lib/shamu/rails/entity.rb +1 -1
- data/lib/shamu/security/policy.rb +1 -2
- data/lib/shamu/services/active_record.rb +16 -0
- data/lib/shamu/services/active_record_crud.rb +32 -22
- data/lib/shamu/services/lazy_transform.rb +31 -0
- data/lib/shamu/services/request_support.rb +3 -2
- data/lib/shamu/services/service.rb +11 -3
- data/lib/shamu/to_model_id_extension.rb +2 -1
- data/lib/shamu/version.rb +2 -1
- data/shamu.gemspec +2 -1
- data/spec/lib/shamu/active_record_support.rb +6 -0
- data/spec/lib/shamu/attributes/assignment_spec.rb +69 -5
- data/spec/lib/shamu/attributes/camel_case_spec.rb +33 -0
- data/spec/lib/shamu/attributes/validation_spec.rb +9 -1
- data/spec/lib/shamu/attributes_spec.rb +4 -0
- data/spec/lib/shamu/entities/active_record_spec.rb +27 -0
- data/spec/lib/shamu/entities/entity_lookup_models.rb +11 -0
- data/spec/lib/shamu/entities/entity_lookup_service_spec.rb +77 -0
- data/spec/lib/shamu/entities/entity_path_spec.rb +3 -4
- data/spec/lib/shamu/entities/list_scope/paging_spec.rb +7 -3
- data/spec/lib/shamu/entities/list_scope/sorting_spec.rb +1 -7
- data/spec/lib/shamu/entities/opaque_entity_lookup_service_spec.rb +39 -0
- data/spec/lib/shamu/entities/opaque_id_spec.rb +30 -0
- data/spec/lib/shamu/entities/paged_list_spec.rb +170 -0
- data/spec/lib/shamu/services/active_record_crud_spec.rb +10 -1
- data/spec/lib/shamu/services/lazy_transform_spec.rb +14 -0
- data/spec/lib/shamu/to_model_id_extension_spec.rb +5 -1
- data/spec/support/active_record.rb +1 -1
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c273a3ff9a688ea2ad15efb7f3136aa203fecda6
|
4
|
+
data.tar.gz: a9f5d0e08e4cdda4e8147c0b58b4c8ab6b46ab63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76c8c84815e68711e085d0a3f372e9b815ffadefb48c76606d3351539dd1ab6e85266f7b548963dd481f79362c8ddcd96d0e3c8e056602f4d8c110b9ec181b67
|
7
|
+
data.tar.gz: 791dc7e9eb66fa9f45ea7fee32d7292e93e4faa24c6cf083b41570269251d450a3155997b894f9a1ec3cb50fd544b9a2322a0387e3a96fe2537a2d9919e67366
|
data/.rubocop.yml
CHANGED
@@ -1,6 +1,24 @@
|
|
1
1
|
AllCops:
|
2
2
|
TargetRubyVersion: 2.3
|
3
3
|
|
4
|
+
Exclude:
|
5
|
+
- "bin/*"
|
6
|
+
- "vendor/bundle/**/*"
|
7
|
+
|
8
|
+
Bundler/OrderedGems:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
Style/EmptyMethod:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/ParallelAssignment:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Lint/AmbiguousBlockAssociation:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Lint/UselessAccessModifier:
|
21
|
+
Enabled: false
|
4
22
|
|
5
23
|
Lint/AmbiguousRegexpLiteral:
|
6
24
|
Enabled: false
|
@@ -11,7 +29,6 @@ Lint/AssignmentInCondition:
|
|
11
29
|
Lint/UnusedMethodArgument:
|
12
30
|
Enabled: false
|
13
31
|
|
14
|
-
|
15
32
|
Metrics/ClassLength:
|
16
33
|
Max: 500
|
17
34
|
|
@@ -33,22 +50,25 @@ Metrics/ModuleLength:
|
|
33
50
|
Metrics/ParameterLists:
|
34
51
|
CountKeywordArgs: false
|
35
52
|
|
53
|
+
Metrics/BlockLength:
|
54
|
+
Enabled: false
|
55
|
+
|
36
56
|
Style/Alias:
|
37
57
|
Enabled: false
|
38
58
|
|
39
|
-
|
59
|
+
Layout/CommentIndentation:
|
40
60
|
Enabled: false
|
41
61
|
|
42
|
-
|
62
|
+
Layout/EmptyLines:
|
43
63
|
Enabled: false
|
44
64
|
|
45
|
-
|
65
|
+
Layout/EmptyLinesAroundBlockBody:
|
46
66
|
Enabled: false
|
47
67
|
|
48
|
-
|
68
|
+
Layout/EmptyLinesAroundClassBody:
|
49
69
|
Enabled: false
|
50
70
|
|
51
|
-
|
71
|
+
Layout/EmptyLinesAroundModuleBody:
|
52
72
|
Enabled: false
|
53
73
|
|
54
74
|
Style/FrozenStringLiteralComment:
|
@@ -66,58 +86,73 @@ Style/GuardClause:
|
|
66
86
|
Style/HashSyntax:
|
67
87
|
Enabled: false
|
68
88
|
|
69
|
-
|
89
|
+
Layout/IndentArray:
|
70
90
|
Enabled: false
|
71
91
|
|
72
|
-
|
92
|
+
Layout/IndentationConsistency:
|
73
93
|
Enabled: false
|
74
94
|
|
75
|
-
|
95
|
+
Layout/IndentationWidth:
|
76
96
|
Enabled: false
|
77
97
|
|
78
98
|
Style/Lambda:
|
79
99
|
Enabled: false
|
80
100
|
|
81
|
-
Style/
|
101
|
+
Style/FrozenStringLiteralComment:
|
82
102
|
Enabled: false
|
83
103
|
|
84
|
-
Style/
|
85
|
-
Enabled:
|
104
|
+
Style/MultilineBlockChain:
|
105
|
+
Enabled: false
|
86
106
|
|
87
|
-
Style/
|
107
|
+
Style/NumericPredicate:
|
88
108
|
Enabled: false
|
89
109
|
|
110
|
+
Style/OptionHash:
|
111
|
+
Enabled: true
|
112
|
+
|
90
113
|
Style/RegexpLiteral:
|
91
114
|
Enabled: false
|
92
115
|
|
93
116
|
Style/SignalException:
|
94
117
|
Enabled: false
|
95
118
|
|
96
|
-
|
119
|
+
Layout/SpaceAroundBlockParameters:
|
97
120
|
Enabled: false
|
98
121
|
|
99
|
-
Style/
|
122
|
+
Style/PercentLiteralDelimiters:
|
100
123
|
Enabled: false
|
101
124
|
|
102
|
-
|
125
|
+
Layout/SpaceAroundOperators:
|
103
126
|
Enabled: false
|
104
127
|
|
105
|
-
|
128
|
+
Layout/SpaceInsideBrackets:
|
106
129
|
Enabled: false
|
107
130
|
|
108
|
-
|
131
|
+
Layout/SpaceInsideParens:
|
132
|
+
Enabled: false
|
133
|
+
|
134
|
+
Layout/SpaceInsideStringInterpolation:
|
109
135
|
EnforcedStyle: space
|
110
136
|
|
137
|
+
Layout/SpaceInsidePercentLiteralDelimiters:
|
138
|
+
Enabled: false
|
139
|
+
|
140
|
+
Style/SpecialGlobalVars:
|
141
|
+
Enabled: false
|
142
|
+
|
143
|
+
Style/SymbolArray:
|
144
|
+
Enabled: false
|
145
|
+
|
111
146
|
Style/StringLiterals:
|
112
147
|
EnforcedStyle: double_quotes
|
113
148
|
|
114
|
-
|
149
|
+
Layout/TrailingBlankLines:
|
115
150
|
Enabled: false
|
116
151
|
|
117
152
|
Style/TrailingCommaInLiteral:
|
118
153
|
Enabled: false
|
119
154
|
|
120
|
-
Style/
|
155
|
+
Style/WhileUntilModifier:
|
121
156
|
Enabled: false
|
122
157
|
|
123
158
|
Style/UnneededInterpolation:
|
data/Gemfile
CHANGED
@@ -16,7 +16,7 @@ group :test do
|
|
16
16
|
|
17
17
|
gem "sqlite3", "~> 1.3.11"
|
18
18
|
gem "guard", "~> 2.12.8"
|
19
|
-
gem "rubocop", "~> 0.
|
19
|
+
gem "rubocop", "~> 0.49.0"
|
20
20
|
gem "guard-rubocop"
|
21
21
|
gem "spring"
|
22
22
|
gem "guard-rspec"
|
@@ -26,10 +26,10 @@ group :test do
|
|
26
26
|
gem "fuubar"
|
27
27
|
gem "yard"
|
28
28
|
gem "yard-activesupport-concern"
|
29
|
-
gem "simplecov"
|
29
|
+
gem "simplecov", "~> 0.14"
|
30
30
|
gem "ruby_gntp", "~> 0.3.4"
|
31
31
|
gem "awesome_print"
|
32
32
|
|
33
|
-
gem "codeclimate-test-reporter", group: :test, require: nil
|
33
|
+
gem "codeclimate-test-reporter", "~> 1.0 ", group: :test, require: nil
|
34
34
|
gem "rspec_junit_formatter", "~> 0.2.2", platforms: :mri
|
35
35
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
shamu (0.0.
|
4
|
+
shamu (0.0.14)
|
5
5
|
activemodel (>= 5.0)
|
6
6
|
activesupport (>= 5.0)
|
7
7
|
crc32 (~> 1)
|
8
8
|
listen (~> 3)
|
9
9
|
loofah (~> 2)
|
10
|
-
multi_json (~> 1.11
|
10
|
+
multi_json (~> 1.11)
|
11
11
|
rack (>= 1)
|
12
12
|
scorpion-ioc (~> 0.6)
|
13
13
|
|
@@ -56,8 +56,8 @@ GEM
|
|
56
56
|
awesome_print (1.7.0)
|
57
57
|
builder (3.2.3)
|
58
58
|
byebug (9.0.6)
|
59
|
-
codeclimate-test-reporter (1.0.
|
60
|
-
simplecov
|
59
|
+
codeclimate-test-reporter (1.0.7)
|
60
|
+
simplecov
|
61
61
|
coderay (1.1.1)
|
62
62
|
combustion (0.6.0)
|
63
63
|
activesupport (>= 3.0.0)
|
@@ -112,7 +112,7 @@ GEM
|
|
112
112
|
mime-types-data (3.2016.0521)
|
113
113
|
mini_portile2 (2.1.0)
|
114
114
|
minitest (5.10.2)
|
115
|
-
multi_json (1.
|
115
|
+
multi_json (1.12.1)
|
116
116
|
nenv (0.3.0)
|
117
117
|
nio4r (2.0.0)
|
118
118
|
nokogiri (1.7.2)
|
@@ -120,6 +120,7 @@ GEM
|
|
120
120
|
notiffany (0.1.1)
|
121
121
|
nenv (~> 0.1)
|
122
122
|
shellany (~> 0.0)
|
123
|
+
parallel (1.11.2)
|
123
124
|
parser (2.4.0.0)
|
124
125
|
ast (~> 2.2)
|
125
126
|
powerpack (0.1.1)
|
@@ -193,8 +194,9 @@ GEM
|
|
193
194
|
rspec_junit_formatter (0.2.3)
|
194
195
|
builder (< 4)
|
195
196
|
rspec-core (>= 2, < 4, != 2.12.0)
|
196
|
-
rubocop (0.
|
197
|
-
|
197
|
+
rubocop (0.49.1)
|
198
|
+
parallel (~> 1.10)
|
199
|
+
parser (>= 2.3.3.1, < 3.0)
|
198
200
|
powerpack (~> 0.1)
|
199
201
|
rainbow (>= 1.99.1, < 3.0)
|
200
202
|
ruby-progressbar (~> 1.7)
|
@@ -205,7 +207,7 @@ GEM
|
|
205
207
|
scorpion-ioc (0.6.0)
|
206
208
|
rails (>= 4.0)
|
207
209
|
shellany (0.0.1)
|
208
|
-
simplecov (0.
|
210
|
+
simplecov (0.14.1)
|
209
211
|
docile (~> 1.1.0)
|
210
212
|
json (>= 1.8, < 3)
|
211
213
|
simplecov-html (~> 0.10.0)
|
@@ -242,7 +244,7 @@ DEPENDENCIES
|
|
242
244
|
awesome_print
|
243
245
|
bundler (~> 1.6)
|
244
246
|
byebug
|
245
|
-
codeclimate-test-reporter
|
247
|
+
codeclimate-test-reporter (~> 1.0)
|
246
248
|
combustion (~> 0.5)
|
247
249
|
fuubar
|
248
250
|
guard (~> 2.12.8)
|
@@ -258,10 +260,10 @@ DEPENDENCIES
|
|
258
260
|
rspec-rails
|
259
261
|
rspec-wait
|
260
262
|
rspec_junit_formatter (~> 0.2.2)
|
261
|
-
rubocop (~> 0.
|
263
|
+
rubocop (~> 0.49.0)
|
262
264
|
ruby_gntp (~> 0.3.4)
|
263
265
|
shamu!
|
264
|
-
simplecov
|
266
|
+
simplecov (~> 0.14)
|
265
267
|
spring
|
266
268
|
sqlite3 (~> 1.3.11)
|
267
269
|
yard
|
data/circle.yml
CHANGED
@@ -5,7 +5,7 @@ database:
|
|
5
5
|
|
6
6
|
test:
|
7
7
|
override:
|
8
|
-
- RAILS_ENV=test bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml
|
8
|
+
- RAILS_ENV=test bundle exec rspec -r rspec_junit_formatter --format progress --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml
|
9
9
|
- bundle exec rubocop
|
10
10
|
|
11
11
|
post:
|
@@ -12,6 +12,30 @@ module Shamu
|
|
12
12
|
public :assign_attributes
|
13
13
|
end
|
14
14
|
|
15
|
+
# @return [Array<Symbol>] the attributes that have been assigned.
|
16
|
+
def assigned_attributes
|
17
|
+
@assigned_attributes.to_a || []
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Array<Symbol>] the attributes that have not been assigned.
|
21
|
+
def unassigned_attributes
|
22
|
+
self.class.attributes.keys - assigned_attributes
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Boolean] true if the attribute as explicitly been defined -
|
26
|
+
# not just present/memoized.
|
27
|
+
def assigned?( name )
|
28
|
+
assigned_attributes.include?( name )
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def assigned_attribute!( name )
|
34
|
+
@assigned_attributes ||= Set.new
|
35
|
+
@assigned_attributes << name
|
36
|
+
end
|
37
|
+
|
38
|
+
|
15
39
|
class_methods do
|
16
40
|
|
17
41
|
# Define a new attribute for the class.
|
@@ -36,7 +60,7 @@ module Shamu
|
|
36
60
|
# attribute :tags, coerce: :to_s, array: true
|
37
61
|
# end
|
38
62
|
def attribute( name, *args, **options, &block )
|
39
|
-
super
|
63
|
+
super( name, *args, **options )
|
40
64
|
define_attribute_assignment( name, **options )
|
41
65
|
define_attribute_writer( name, **options )
|
42
66
|
end
|
@@ -52,6 +76,7 @@ module Shamu
|
|
52
76
|
|
53
77
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
54
78
|
def assign_#{ name }( *values )
|
79
|
+
assigned_attribute!( :#{ name } )
|
55
80
|
@#{ name } = coerce_#{ name }#{ array ? '_array' : '' }( *values )
|
56
81
|
end
|
57
82
|
RUBY
|
@@ -73,10 +98,14 @@ module Shamu
|
|
73
98
|
private :"coerce_#{ name }_array"
|
74
99
|
end
|
75
100
|
|
76
|
-
def define_attribute_coercion( name, coerce )
|
101
|
+
def define_attribute_coercion( name, coerce ) # rubocop:disable Metrics/PerceivedComplexity
|
77
102
|
coerce = cource_method( name, coerce )
|
78
103
|
|
79
|
-
if
|
104
|
+
if coerce.is_a?( Class )
|
105
|
+
define_method :"coerce_#{ name }" do |value|
|
106
|
+
coerce.new( value ) if value
|
107
|
+
end
|
108
|
+
elsif !coerce || coerce.is_a?( Symbol )
|
80
109
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
81
110
|
def coerce_#{ name }( value )
|
82
111
|
value#{ coerce && ".#{ coerce }" }
|
@@ -93,7 +122,7 @@ module Shamu
|
|
93
122
|
if coerce == :smart
|
94
123
|
case name
|
95
124
|
when /_at$/, /_on$/ then :to_datetime
|
96
|
-
when /
|
125
|
+
when /(^|_)ids?$/ then :to_model_id
|
97
126
|
end
|
98
127
|
else
|
99
128
|
coerce
|
@@ -107,8 +136,18 @@ module Shamu
|
|
107
136
|
alias_method :"#{ as }=", :"#{ name }=" if as
|
108
137
|
end
|
109
138
|
|
139
|
+
def define_attribute_reader( name, as: nil, ** )
|
140
|
+
super
|
141
|
+
|
142
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
143
|
+
def #{ name }_assigned? # def attribute_assigned?
|
144
|
+
assigned?( :#{ name } ) # assigned( :attribute )
|
145
|
+
end # end
|
146
|
+
RUBY
|
147
|
+
end
|
148
|
+
|
110
149
|
end
|
111
150
|
|
112
151
|
end
|
113
152
|
end
|
114
|
-
end
|
153
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Shamu
|
2
|
+
module Attributes
|
3
|
+
|
4
|
+
# Automatically add camelCase aliases for all attributes.
|
5
|
+
module CamelCase
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do |base|
|
9
|
+
raise "Must include Shamu::Attributes first." unless base < Shamu::Attributes
|
10
|
+
end
|
11
|
+
|
12
|
+
class_methods do
|
13
|
+
def attribute( name, *args, **options, &block )
|
14
|
+
options[ :as ] ||= name.to_s.camelize( :lower ).to_sym
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -46,7 +46,11 @@ module Shamu
|
|
46
46
|
super
|
47
47
|
|
48
48
|
validation_options = options.each_with_object({}) do |(key, value), opts|
|
49
|
-
|
49
|
+
next if attribute_option_keys.include?( key )
|
50
|
+
|
51
|
+
validator = "#{ key.to_s.camelize }Validator"
|
52
|
+
key = "shamu/attributes/validators/#{ key }" if Shamu::Attributes::Validators.const_defined?( validator.to_sym ) # rubocop:disable Metrics/LineLength
|
53
|
+
opts[ key ] = value
|
50
54
|
end
|
51
55
|
validates name, validation_options if validation_options.any?
|
52
56
|
end
|
@@ -67,6 +71,14 @@ module Shamu
|
|
67
71
|
@validated = true
|
68
72
|
run_validations!
|
69
73
|
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def assign_attribute!( * )
|
78
|
+
# If any attribute changes we should re-run the validations
|
79
|
+
@validated = false
|
80
|
+
super
|
81
|
+
end
|
70
82
|
end
|
71
83
|
|
72
84
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Shamu
|
2
|
+
module Attributes
|
3
|
+
module Validators
|
4
|
+
# Validates that an attribute's value returns true for `valid?`.
|
5
|
+
#
|
6
|
+
# validates :nested_request, valid: true
|
7
|
+
class ValidValidator < ActiveModel::EachValidator
|
8
|
+
def validate_each( record, attribute, value )
|
9
|
+
record.errors.add attribute, :invalid if value && !value.valid?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/shamu/attributes.rb
CHANGED
@@ -27,7 +27,9 @@ module Shamu
|
|
27
27
|
require "shamu/attributes/assignment"
|
28
28
|
require "shamu/attributes/fluid_assignment"
|
29
29
|
require "shamu/attributes/validation"
|
30
|
+
require "shamu/attributes/validators"
|
30
31
|
require "shamu/attributes/equality"
|
32
|
+
require "shamu/attributes/camel_case"
|
31
33
|
require "shamu/attributes/html_sanitation"
|
32
34
|
|
33
35
|
def initialize( *attributes )
|
@@ -108,19 +110,18 @@ module Shamu
|
|
108
110
|
|
109
111
|
def build_value( build, value )
|
110
112
|
if build.is_a?( Class )
|
111
|
-
|
112
|
-
|
113
|
+
build.new( value )
|
114
|
+
else
|
115
|
+
build.call( value )
|
113
116
|
end
|
114
|
-
|
115
|
-
build.call( value )
|
116
117
|
end
|
117
118
|
|
118
119
|
def resolve_attributes( attributes )
|
119
120
|
if attributes.respond_to?( :to_attributes )
|
120
121
|
attributes.to_attributes
|
121
122
|
# Allow protected attributes to be used without explicitly being set.
|
122
|
-
# All 'Attributes' classes are
|
123
|
-
# attributes.
|
123
|
+
# All 'Attributes' classes are themselves the explicit set of permitted
|
124
|
+
# attributes so there is no danger of 'over assignment'.
|
124
125
|
elsif attributes.respond_to?( :to_unsafe_h )
|
125
126
|
attributes.to_unsafe_h
|
126
127
|
elsif attributes.respond_to?( :to_hash )
|
@@ -161,7 +162,7 @@ module Shamu
|
|
161
162
|
# to.
|
162
163
|
# @param [Object,#call] default value if not set.
|
163
164
|
# @param [Class,#call] build method used to build a nested object on
|
164
|
-
#
|
165
|
+
# assignment of a hash with nested keys.
|
165
166
|
# @param [Boolean] serialize true if the attribute should be included in
|
166
167
|
# {#to_attributes}. Default true.
|
167
168
|
# @yieldreturn the value of the attribute. The result is memoized so the
|
@@ -203,7 +204,7 @@ module Shamu
|
|
203
204
|
# @return [Array<Symbol>] keys used by the {.attribute} method options
|
204
205
|
# argument. Used by {Attributes::Validation} to filter option keys.
|
205
206
|
def attribute_option_keys
|
206
|
-
[ :on, :build, :default, :serialize ]
|
207
|
+
[ :on, :build, :default, :serialize, :as ]
|
207
208
|
end
|
208
209
|
|
209
210
|
def create_attribute( name, *args, **options )
|
@@ -219,6 +220,10 @@ module Shamu
|
|
219
220
|
return @#{ name } if defined? @#{ name } # return @attribute if defined? @attribute
|
220
221
|
@#{ name } = fetch_#{ name } # @attribute = fetch_attribute
|
221
222
|
end # end
|
223
|
+
|
224
|
+
def #{ name }_set? # def attribute_set?
|
225
|
+
defined? @#{ name } # defined? @attribute
|
226
|
+
end # end
|
222
227
|
RUBY
|
223
228
|
|
224
229
|
alias_method as, name if as
|
@@ -13,11 +13,7 @@ module Shamu
|
|
13
13
|
class AuditingService < Services::Service
|
14
14
|
|
15
15
|
def self.create( scorpion, *args )
|
16
|
-
|
17
|
-
scorpion.fetch Shamu::Auditing::ActiveRecord::Service, *args
|
18
|
-
else
|
19
|
-
fail "No available auditing service available."
|
20
|
-
end
|
16
|
+
scorpion.fetch Shamu::Auditing::LoggingAuditingService, *args
|
21
17
|
end
|
22
18
|
|
23
19
|
# Records an auditable event in persistent storage.
|
@@ -24,6 +24,14 @@ module Shamu
|
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
+
# @!visibility public
|
28
|
+
#
|
29
|
+
# Same as {#audit_request} but does not validate the request before
|
30
|
+
# yielding to the block.
|
31
|
+
def audit_partial_request( params, request_class, action: :smart, &block )
|
32
|
+
perform_audit_request( :with_partial_request, params, request_class, action: action, &block )
|
33
|
+
end
|
34
|
+
|
27
35
|
# @!visibility public
|
28
36
|
#
|
29
37
|
# Audit the requested changes and report the request to the
|
@@ -40,10 +48,14 @@ module Shamu
|
|
40
48
|
# should call {Transaction#append_entity} to include any parent
|
41
49
|
# entities in the entity path.
|
42
50
|
def audit_request( params, request_class, action: :smart, &block )
|
51
|
+
perform_audit_request( :with_request, params, request_class, action: action, &block )
|
52
|
+
end
|
53
|
+
|
54
|
+
def perform_audit_request( method, params, request_class, action: :smart, &block )
|
43
55
|
transaction = Transaction.new \
|
44
56
|
user_id_chain: auditing_security_principal.user_id_chain
|
45
57
|
|
46
|
-
result =
|
58
|
+
result = send method, params, request_class do |request|
|
47
59
|
transaction.action = audit_request_action( request, action )
|
48
60
|
transaction.changes = request.to_attributes
|
49
61
|
|
@@ -72,4 +84,4 @@ module Shamu
|
|
72
84
|
end
|
73
85
|
end
|
74
86
|
end
|
75
|
-
end
|
87
|
+
end
|
@@ -30,6 +30,7 @@ module Shamu
|
|
30
30
|
criteria = apply_custom_list_scope( criteria, scope )
|
31
31
|
criteria = apply_paging_scope( criteria, scope ) if scope.respond_to?( :paged? )
|
32
32
|
criteria = apply_scoped_paging_scope( criteria, scope ) if scope.respond_to?( :scoped_page? )
|
33
|
+
criteria = apply_window_paging_scope( criteria, scope ) if scope.respond_to?( :window_paged? )
|
33
34
|
criteria = apply_dates_scope( criteria, scope ) if scope.respond_to?( :dated? )
|
34
35
|
criteria = apply_sorting_scope( criteria, scope ) if scope.respond_to?( :sorted? )
|
35
36
|
criteria
|
@@ -60,7 +61,7 @@ module Shamu
|
|
60
61
|
|
61
62
|
def apply_sorting_scope( criteria, scope )
|
62
63
|
if scope.sort_by
|
63
|
-
criteria = scope.
|
64
|
+
criteria = scope.sort_by_resolved.reduce( criteria ) do |crit, ( field, direction )|
|
64
65
|
apply_sort( crit, field, direction )
|
65
66
|
end
|
66
67
|
end
|
@@ -84,6 +85,18 @@ module Shamu
|
|
84
85
|
criteria
|
85
86
|
end
|
86
87
|
|
88
|
+
def apply_window_paging_scope( criteria, scope )
|
89
|
+
if scope.window_paged?
|
90
|
+
criteria = criteria.page( 1 )
|
91
|
+
criteria = criteria.per( scope.first ) if scope.first
|
92
|
+
criteria = criteria.padding( scope.after ) if scope.after
|
93
|
+
criteria = criteria.per( scope.last ) if scope.last
|
94
|
+
criteria = criteria.padding( scope.before ) if scope.before
|
95
|
+
end
|
96
|
+
|
97
|
+
criteria
|
98
|
+
end
|
99
|
+
|
87
100
|
def apply_dates_scope( criteria, scope )
|
88
101
|
criteria = criteria.where( criteria.arel_table[:since].gteq( scope.since ) ) if scope.since
|
89
102
|
criteria = criteria.where( criteria.arel_table[:until].lteq( scope.until ) ) if scope.until
|
@@ -114,10 +127,11 @@ module Shamu
|
|
114
127
|
class StandardListScopeTemplate < ListScope
|
115
128
|
include ListScope::Paging
|
116
129
|
include ListScope::ScopedPaging
|
130
|
+
include ListScope::WindowPaging
|
117
131
|
include ListScope::Dates
|
118
132
|
include ListScope::Sorting
|
119
133
|
end
|
120
134
|
|
121
135
|
end
|
122
136
|
end
|
123
|
-
end
|
137
|
+
end
|
@@ -29,12 +29,16 @@ module Shamu
|
|
29
29
|
# @return [ActiveRecord::Relation]
|
30
30
|
scope :destroyed, ->() { unscope( where: :destroyed_at ).where( arel_table[ :destroyed_at ].not_eq( nil ) ) }
|
31
31
|
|
32
|
+
# Limit the records to those that have not been destroyed.
|
33
|
+
# @return [ActiveRecord::Relation]
|
34
|
+
scope :except_destroyed, ->() { unscope( where: :destroyed_at ).where( arel_table[ :destroyed_at ].eq( nil ) ) }
|
35
|
+
|
32
36
|
# Include live and soft destroyed records.
|
33
37
|
# @return [ActiveRecord::Relation]
|
34
38
|
scope :including_destroyed, ->() { unscope( where: :destroyed_at ) }
|
35
39
|
|
36
|
-
# Exclude destroyed records by
|
37
|
-
default_scope {
|
40
|
+
# Exclude destroyed records by default.
|
41
|
+
default_scope { except_destroyed }
|
38
42
|
|
39
43
|
#
|
40
44
|
# @!endgroup Scopes
|
@@ -88,4 +92,4 @@ module Shamu
|
|
88
92
|
|
89
93
|
end
|
90
94
|
end
|
91
|
-
end
|
95
|
+
end
|