shamu 0.0.13 → 0.0.14

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +55 -20
  3. data/Gemfile +3 -3
  4. data/Gemfile.lock +13 -11
  5. data/circle.yml +1 -1
  6. data/lib/shamu/attributes/assignment.rb +44 -5
  7. data/lib/shamu/attributes/camel_case.rb +21 -0
  8. data/lib/shamu/attributes/validation.rb +13 -1
  9. data/lib/shamu/attributes/validators/valid_validator.rb +14 -0
  10. data/lib/shamu/attributes/validators.rb +7 -0
  11. data/lib/shamu/attributes.rb +13 -8
  12. data/lib/shamu/auditing/auditing_service.rb +1 -5
  13. data/lib/shamu/auditing/support.rb +14 -2
  14. data/lib/shamu/entities/active_record.rb +16 -2
  15. data/lib/shamu/entities/active_record_soft_destroy.rb +7 -3
  16. data/lib/shamu/entities/entity.rb +1 -1
  17. data/lib/shamu/entities/entity_lookup_service.rb +137 -0
  18. data/lib/shamu/entities/entity_path.rb +6 -9
  19. data/lib/shamu/entities/list.rb +8 -2
  20. data/lib/shamu/entities/list_scope/paging.rb +3 -3
  21. data/lib/shamu/entities/list_scope/sorting.rb +21 -2
  22. data/lib/shamu/entities/list_scope/window_paging.rb +96 -0
  23. data/lib/shamu/entities/list_scope.rb +2 -2
  24. data/lib/shamu/entities/opaque_entity_lookup_service.rb +59 -0
  25. data/lib/shamu/entities/opaque_id.rb +54 -0
  26. data/lib/shamu/entities/paged_list.rb +137 -0
  27. data/lib/shamu/entities.rb +5 -1
  28. data/lib/shamu/events/active_record/service.rb +1 -2
  29. data/lib/shamu/events/in_memory/service.rb +1 -2
  30. data/lib/shamu/features/conditions/percentage.rb +3 -3
  31. data/lib/shamu/features/features_service.rb +2 -2
  32. data/lib/shamu/features/toggle.rb +2 -3
  33. data/lib/shamu/json_api/context.rb +0 -1
  34. data/lib/shamu/json_api/rails/controller.rb +0 -2
  35. data/lib/shamu/rails/controller.rb +0 -1
  36. data/lib/shamu/rails/entity.rb +1 -1
  37. data/lib/shamu/security/policy.rb +1 -2
  38. data/lib/shamu/services/active_record.rb +16 -0
  39. data/lib/shamu/services/active_record_crud.rb +32 -22
  40. data/lib/shamu/services/lazy_transform.rb +31 -0
  41. data/lib/shamu/services/request_support.rb +3 -2
  42. data/lib/shamu/services/service.rb +11 -3
  43. data/lib/shamu/to_model_id_extension.rb +2 -1
  44. data/lib/shamu/version.rb +2 -1
  45. data/shamu.gemspec +2 -1
  46. data/spec/lib/shamu/active_record_support.rb +6 -0
  47. data/spec/lib/shamu/attributes/assignment_spec.rb +69 -5
  48. data/spec/lib/shamu/attributes/camel_case_spec.rb +33 -0
  49. data/spec/lib/shamu/attributes/validation_spec.rb +9 -1
  50. data/spec/lib/shamu/attributes_spec.rb +4 -0
  51. data/spec/lib/shamu/entities/active_record_spec.rb +27 -0
  52. data/spec/lib/shamu/entities/entity_lookup_models.rb +11 -0
  53. data/spec/lib/shamu/entities/entity_lookup_service_spec.rb +77 -0
  54. data/spec/lib/shamu/entities/entity_path_spec.rb +3 -4
  55. data/spec/lib/shamu/entities/list_scope/paging_spec.rb +7 -3
  56. data/spec/lib/shamu/entities/list_scope/sorting_spec.rb +1 -7
  57. data/spec/lib/shamu/entities/opaque_entity_lookup_service_spec.rb +39 -0
  58. data/spec/lib/shamu/entities/opaque_id_spec.rb +30 -0
  59. data/spec/lib/shamu/entities/paged_list_spec.rb +170 -0
  60. data/spec/lib/shamu/services/active_record_crud_spec.rb +10 -1
  61. data/spec/lib/shamu/services/lazy_transform_spec.rb +14 -0
  62. data/spec/lib/shamu/to_model_id_extension_spec.rb +5 -1
  63. data/spec/support/active_record.rb +1 -1
  64. metadata +24 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b2e88c67ffd19033c4fafc5933fb288f8538a709
4
- data.tar.gz: daaf1a9d1f8dcd9746f335ef0fa6122aa7c9dfa0
3
+ metadata.gz: c273a3ff9a688ea2ad15efb7f3136aa203fecda6
4
+ data.tar.gz: a9f5d0e08e4cdda4e8147c0b58b4c8ab6b46ab63
5
5
  SHA512:
6
- metadata.gz: 74934132c1023791f4fff72aa458ae8815c72138044bc33b0de60a39d71802e7c976f8409b675a7bb67644d377576370ed3e88a79c21bce48a6b8fbca698c7b3
7
- data.tar.gz: '00095f967a07a2517a92721450ab45b2ee991d43f526fcde7b9bb853ea8f98dd4dd014f000d8ff46247e83be0cd62cb93513491df24b79f1a73be1c1f293b3e0'
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
- Style/CommentIndentation:
59
+ Layout/CommentIndentation:
40
60
  Enabled: false
41
61
 
42
- Style/EmptyLines:
62
+ Layout/EmptyLines:
43
63
  Enabled: false
44
64
 
45
- Style/EmptyLinesAroundBlockBody:
65
+ Layout/EmptyLinesAroundBlockBody:
46
66
  Enabled: false
47
67
 
48
- Style/EmptyLinesAroundClassBody:
68
+ Layout/EmptyLinesAroundClassBody:
49
69
  Enabled: false
50
70
 
51
- Style/EmptyLinesAroundModuleBody:
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
- Style/IndentArray:
89
+ Layout/IndentArray:
70
90
  Enabled: false
71
91
 
72
- Style/IndentationConsistency:
92
+ Layout/IndentationConsistency:
73
93
  Enabled: false
74
94
 
75
- Style/IndentationWidth:
95
+ Layout/IndentationWidth:
76
96
  Enabled: false
77
97
 
78
98
  Style/Lambda:
79
99
  Enabled: false
80
100
 
81
- Style/MultilineBlockChain:
101
+ Style/FrozenStringLiteralComment:
82
102
  Enabled: false
83
103
 
84
- Style/OptionHash:
85
- Enabled: true
104
+ Style/MultilineBlockChain:
105
+ Enabled: false
86
106
 
87
- Style/ParallelAssignment:
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
- Style/SpaceAroundBlockParameters:
119
+ Layout/SpaceAroundBlockParameters:
97
120
  Enabled: false
98
121
 
99
- Style/SpaceAroundOperators:
122
+ Style/PercentLiteralDelimiters:
100
123
  Enabled: false
101
124
 
102
- Style/SpaceInsideBrackets:
125
+ Layout/SpaceAroundOperators:
103
126
  Enabled: false
104
127
 
105
- Style/SpaceInsideParens:
128
+ Layout/SpaceInsideBrackets:
106
129
  Enabled: false
107
130
 
108
- Style/SpaceInsideStringInterpolation:
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
- Style/TrailingBlankLines:
149
+ Layout/TrailingBlankLines:
115
150
  Enabled: false
116
151
 
117
152
  Style/TrailingCommaInLiteral:
118
153
  Enabled: false
119
154
 
120
- Style/TrivialAccessors:
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.39.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.13)
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.2)
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.8)
60
- simplecov (<= 0.13)
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.11.3)
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.39.0)
197
- parser (>= 2.3.0.7, < 3.0)
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.13.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.39.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 !coerce || coerce.is_a?( Symbol )
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 /_ids?$/ then :to_i
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
- opts[key] = value unless attribute_option_keys.include?( key )
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
@@ -0,0 +1,7 @@
1
+ module Shamu
2
+ module Attributes
3
+ module Validators
4
+ require "shamu/attributes/validators/valid_validator"
5
+ end
6
+ end
7
+ end
@@ -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
- klass = build
112
- build = ->(v) { klass.new( v ) }
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 them selves the explicit set of permitted
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
- # assignement of a hash with nested keys.
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
- if defined? ActiveRecord
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 = with_request params, request_class do |request|
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.sort_by.reduce( criteria ) do |crit, ( field, direction )|
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 dfault.
37
- default_scope { where( destroyed_at: nil ) }
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
@@ -196,4 +196,4 @@ module Shamu
196
196
  end
197
197
  end
198
198
  end
199
- end
199
+ end