granite-form 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -2
  3. data/.github/workflows/{ci.yml → ruby.yml} +22 -4
  4. data/.rubocop.yml +1 -1
  5. data/.rubocop_todo.yml +3 -3
  6. data/Appraisals +1 -2
  7. data/CHANGELOG.md +7 -0
  8. data/README.md +0 -2
  9. data/docker-compose.yml +14 -0
  10. data/gemfiles/rails.5.0.gemfile +0 -1
  11. data/gemfiles/rails.5.1.gemfile +0 -1
  12. data/gemfiles/rails.5.2.gemfile +0 -1
  13. data/granite-form.gemspec +15 -15
  14. data/lib/granite/form/active_record/associations.rb +1 -1
  15. data/lib/granite/form/base.rb +1 -2
  16. data/lib/granite/form/errors.rb +0 -15
  17. data/lib/granite/form/model/associations/base.rb +0 -4
  18. data/lib/granite/form/model/associations/collection/embedded.rb +2 -1
  19. data/lib/granite/form/model/associations/collection/proxy.rb +1 -1
  20. data/lib/granite/form/model/associations/embeds_any.rb +7 -0
  21. data/lib/granite/form/model/associations/embeds_many.rb +9 -58
  22. data/lib/granite/form/model/associations/embeds_one.rb +7 -36
  23. data/lib/granite/form/model/associations/nested_attributes.rb +5 -5
  24. data/lib/granite/form/model/associations/persistence_adapters/active_record.rb +0 -4
  25. data/lib/granite/form/model/associations/persistence_adapters/base.rb +0 -4
  26. data/lib/granite/form/model/associations/references_many.rb +0 -32
  27. data/lib/granite/form/model/associations/references_one.rb +0 -28
  28. data/lib/granite/form/model/associations/reflections/embeds_any.rb +1 -1
  29. data/lib/granite/form/model/associations/reflections/references_any.rb +0 -4
  30. data/lib/granite/form/model/associations/reflections/references_one.rb +0 -2
  31. data/lib/granite/form/model/associations/reflections/singular.rb +0 -8
  32. data/lib/granite/form/model/associations.rb +0 -6
  33. data/lib/granite/form/model/attributes/base.rb +1 -1
  34. data/lib/granite/form/model/attributes/reflections/attribute.rb +0 -6
  35. data/lib/granite/form/model/attributes/reflections/base.rb +8 -7
  36. data/lib/granite/form/model/attributes/reflections/reference_one.rb +0 -6
  37. data/lib/granite/form/model/persistence.rb +1 -19
  38. data/lib/granite/form/model.rb +0 -2
  39. data/lib/granite/form/version.rb +1 -1
  40. data/spec/granite/form/active_record/associations_spec.rb +16 -18
  41. data/spec/granite/form/model/associations/embeds_many_spec.rb +29 -305
  42. data/spec/granite/form/model/associations/embeds_one_spec.rb +27 -212
  43. data/spec/granite/form/model/associations/nested_attributes_spec.rb +0 -95
  44. data/spec/granite/form/model/associations/references_many_spec.rb +5 -326
  45. data/spec/granite/form/model/associations/references_one_spec.rb +6 -278
  46. data/spec/granite/form/model/associations/reflections/embeds_any_spec.rb +1 -2
  47. data/spec/granite/form/model/associations/reflections/embeds_many_spec.rb +18 -26
  48. data/spec/granite/form/model/associations/reflections/embeds_one_spec.rb +16 -23
  49. data/spec/granite/form/model/associations/reflections/references_many_spec.rb +1 -1
  50. data/spec/granite/form/model/associations/reflections/references_one_spec.rb +1 -22
  51. data/spec/granite/form/model/associations/validations_spec.rb +0 -3
  52. data/spec/granite/form/model/associations_spec.rb +3 -24
  53. data/spec/granite/form/model/dirty_spec.rb +1 -1
  54. data/spec/granite/form/model/persistence_spec.rb +0 -2
  55. data/spec/granite/form/model/validations/associated_spec.rb +2 -4
  56. data/spec/granite/form/model/validations/nested_spec.rb +2 -4
  57. data/spec/spec_helper.rb +0 -15
  58. data/spec/support/active_record.rb +20 -0
  59. data/spec/support/shared/nested_attribute_examples.rb +3 -21
  60. metadata +32 -38
  61. data/.github/workflows/main.yml +0 -29
  62. data/gemfiles/rails.4.2.gemfile +0 -15
  63. data/lib/granite/form/model/callbacks.rb +0 -72
  64. data/lib/granite/form/model/lifecycle.rb +0 -309
  65. data/spec/granite/form/model/callbacks_spec.rb +0 -337
  66. data/spec/granite/form/model/lifecycle_spec.rb +0 -356
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: granite-form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
- - pyromaniac
7
+ - Toptal Engineering
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-12 00:00:00.000000000 Z
11
+ date: 2022-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.0'
19
+ version: '5.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.0'
26
+ version: '5.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '4.0'
33
+ version: '5.0'
34
34
  type: :development
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: '4.0'
40
+ version: '5.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: appraisal
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pg
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -136,20 +150,6 @@ dependencies:
136
150
  - - '='
137
151
  - !ruby/object:Gem::Version
138
152
  version: 0.52.1
139
- - !ruby/object:Gem::Dependency
140
- name: sqlite3
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: uuidtools
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -170,28 +170,28 @@ dependencies:
170
170
  requirements:
171
171
  - - ">="
172
172
  - !ruby/object:Gem::Version
173
- version: '4.0'
173
+ version: '5.0'
174
174
  type: :runtime
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
- version: '4.0'
180
+ version: '5.0'
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: activesupport
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - ">="
186
186
  - !ruby/object:Gem::Version
187
- version: '4.0'
187
+ version: '5.0'
188
188
  type: :runtime
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - ">="
193
193
  - !ruby/object:Gem::Version
194
- version: '4.0'
194
+ version: '5.0'
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: tzinfo
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -207,16 +207,14 @@ dependencies:
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0'
209
209
  description: Making object from any hash or hash array
210
- email:
211
- - kinwizard@gmail.com
210
+ email:
212
211
  executables: []
213
212
  extensions: []
214
213
  extra_rdoc_files: []
215
214
  files:
216
215
  - ".codeclimate.yml"
217
216
  - ".github/CODEOWNERS"
218
- - ".github/workflows/ci.yml"
219
- - ".github/workflows/main.yml"
217
+ - ".github/workflows/ruby.yml"
220
218
  - ".gitignore"
221
219
  - ".rspec"
222
220
  - ".rubocop.yml"
@@ -228,7 +226,7 @@ files:
228
226
  - LICENSE
229
227
  - README.md
230
228
  - Rakefile
231
- - gemfiles/rails.4.2.gemfile
229
+ - docker-compose.yml
232
230
  - gemfiles/rails.5.0.gemfile
233
231
  - gemfiles/rails.5.1.gemfile
234
232
  - gemfiles/rails.5.2.gemfile
@@ -284,10 +282,8 @@ files:
284
282
  - lib/granite/form/model/attributes/reflections/reference_one.rb
285
283
  - lib/granite/form/model/attributes/reflections/represents.rb
286
284
  - lib/granite/form/model/attributes/represents.rb
287
- - lib/granite/form/model/callbacks.rb
288
285
  - lib/granite/form/model/conventions.rb
289
286
  - lib/granite/form/model/dirty.rb
290
- - lib/granite/form/model/lifecycle.rb
291
287
  - lib/granite/form/model/localization.rb
292
288
  - lib/granite/form/model/persistence.rb
293
289
  - lib/granite/form/model/primary.rb
@@ -343,10 +339,8 @@ files:
343
339
  - spec/granite/form/model/attributes/reflections/represents_spec.rb
344
340
  - spec/granite/form/model/attributes/represents_spec.rb
345
341
  - spec/granite/form/model/attributes_spec.rb
346
- - spec/granite/form/model/callbacks_spec.rb
347
342
  - spec/granite/form/model/conventions_spec.rb
348
343
  - spec/granite/form/model/dirty_spec.rb
349
- - spec/granite/form/model/lifecycle_spec.rb
350
344
  - spec/granite/form/model/persistence_spec.rb
351
345
  - spec/granite/form/model/primary_spec.rb
352
346
  - spec/granite/form/model/representation_spec.rb
@@ -370,12 +364,13 @@ files:
370
364
  - spec/granite/form/types/uuid_spec.rb
371
365
  - spec/granite/form_spec.rb
372
366
  - spec/spec_helper.rb
367
+ - spec/support/active_record.rb
373
368
  - spec/support/model_helpers.rb
374
369
  - spec/support/muffle_helper.rb
375
370
  - spec/support/shared/nested_attribute_examples.rb
376
371
  - spec/support/shared/type_examples.rb
377
372
  - spec/support/translations.rb
378
- homepage: ''
373
+ homepage: https://github.com/toptal/granite-form
379
374
  licenses: []
380
375
  metadata: {}
381
376
  post_install_message:
@@ -386,7 +381,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
386
381
  requirements:
387
382
  - - ">="
388
383
  - !ruby/object:Gem::Version
389
- version: '0'
384
+ version: 2.4.0
390
385
  required_rubygems_version: !ruby/object:Gem::Requirement
391
386
  requirements:
392
387
  - - ">="
@@ -428,10 +423,8 @@ test_files:
428
423
  - spec/granite/form/model/attributes/reflections/represents_spec.rb
429
424
  - spec/granite/form/model/attributes/represents_spec.rb
430
425
  - spec/granite/form/model/attributes_spec.rb
431
- - spec/granite/form/model/callbacks_spec.rb
432
426
  - spec/granite/form/model/conventions_spec.rb
433
427
  - spec/granite/form/model/dirty_spec.rb
434
- - spec/granite/form/model/lifecycle_spec.rb
435
428
  - spec/granite/form/model/persistence_spec.rb
436
429
  - spec/granite/form/model/primary_spec.rb
437
430
  - spec/granite/form/model/representation_spec.rb
@@ -455,6 +448,7 @@ test_files:
455
448
  - spec/granite/form/types/uuid_spec.rb
456
449
  - spec/granite/form_spec.rb
457
450
  - spec/spec_helper.rb
451
+ - spec/support/active_record.rb
458
452
  - spec/support/model_helpers.rb
459
453
  - spec/support/muffle_helper.rb
460
454
  - spec/support/shared/nested_attribute_examples.rb
@@ -1,29 +0,0 @@
1
- name: Ruby
2
-
3
- on: [push]
4
-
5
- jobs:
6
- spec:
7
- runs-on: ubuntu-latest
8
- name: Run specs in ruby v${{ matrix.ruby }} rails v${{ matrix.rails }}
9
- strategy:
10
- matrix:
11
- ruby: [ '2.6', '2.7', '3.0' ]
12
- rails: [ '6.0', '6.1' ]
13
- steps:
14
- - uses: actions/checkout@v2
15
-
16
- - name: Set up Ruby
17
- uses: ruby/setup-ruby@v1
18
- with:
19
- ruby-version: ${{ matrix.ruby }}
20
-
21
- - name: Install dependencies
22
- env:
23
- BUNDLE_GEMFILE: gemfiles/rails.${{ matrix.rails }}.gemfile
24
- run: bundle install
25
-
26
- - name: Run specs
27
- env:
28
- BUNDLE_GEMFILE: gemfiles/rails.${{ matrix.rails }}.gemfile
29
- run: bundle exec rake spec
@@ -1,15 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activesupport", "~> 4.2.0"
6
- gem "activemodel", "~> 4.2.0"
7
- gem "activerecord", "~> 4.2.0"
8
- gem "sqlite3", "~> 1.3.6"
9
-
10
- group :test do
11
- gem "guard"
12
- gem "guard-rspec"
13
- end
14
-
15
- gemspec path: "../"
@@ -1,72 +0,0 @@
1
- module Granite
2
- module Form
3
- module Model
4
- # == Callbacks for Granite::Form::Model lifecycle
5
- #
6
- # Provides ActiveModel callbacks support for lifecycle
7
- # actions.
8
- #
9
- # class Book
10
- # include Granite::Form::Model
11
- #
12
- # attribute :id, Integer
13
- # attribute :title, String
14
- #
15
- # define_save do
16
- # REDIS.set(id, attributes.to_json)
17
- # end
18
- #
19
- # define_destroy do
20
- # REDIS.del(instance.id)
21
- # end
22
- #
23
- # after_initialize :setup_id
24
- # before_save :do_something
25
- # around_update do |&block|
26
- # ...
27
- # block.call
28
- # ...
29
- # end
30
- # after_destroy { ... }
31
- # end
32
- #
33
- module Callbacks
34
- extend ActiveSupport::Concern
35
-
36
- included do
37
- extend ActiveModel::Callbacks
38
-
39
- include ActiveModel::Validations::Callbacks
40
- include Lifecycle
41
- prepend PrependMethods
42
-
43
- define_model_callbacks :initialize, only: :after
44
- define_model_callbacks :save, :create, :update, :destroy
45
- end
46
-
47
- module PrependMethods
48
- def initialize(*_)
49
- super
50
- run_callbacks :initialize
51
- end
52
-
53
- def save_object(&block)
54
- run_callbacks(:save) { super(&block) }
55
- end
56
-
57
- def create_object(&block)
58
- run_callbacks(:create) { super(&block) }
59
- end
60
-
61
- def update_object(&block)
62
- run_callbacks(:update) { super(&block) }
63
- end
64
-
65
- def destroy_object(&block)
66
- run_callbacks(:destroy) { super(&block) }
67
- end
68
- end
69
- end
70
- end
71
- end
72
- end
@@ -1,309 +0,0 @@
1
- module Granite
2
- module Form
3
- module Model
4
- # == Lifecycle methods for Granite::Form::Model
5
- #
6
- # Provides methods +save+ and +destroy+ and its bang variants.
7
- # Also, patches +create+ and +update_attributes+ methods by adding
8
- # save at the end.
9
- #
10
- # You can define save or destroy performers with <tt>define_<action></tt>
11
- # methods. Create and update performers might be defined instead of
12
- # save performer:
13
- #
14
- # class Book
15
- # include Granite::Form::Model
16
- # include Granite::Form::Model::Lifecycle
17
- #
18
- # attribute :id, Integer
19
- # attribute :title, String
20
- #
21
- # define_save do # executes in the instance scope
22
- # REDIS.set(id, attributes.to_json)
23
- # end
24
- #
25
- # define_destroy do
26
- # REDIS.del(id)
27
- # end
28
- # end
29
- #
30
- # class Author
31
- # include Granite::Form::Model
32
- # include Granite::Form::Model::Lifecycle
33
- #
34
- # attribute :id, Integer
35
- # attribute :name, String
36
- #
37
- # define_create do # will be called on create only
38
- # REDIS.sadd('author_ids', id)
39
- # REDIS.set(id, attributes.to_json)
40
- # end
41
- #
42
- # define_update do # will be called on update only
43
- # REDIS.set(id, attributes.to_json)
44
- # end
45
- # end
46
- #
47
- # In case of undefined performer Granite::Form::UnsavableObject
48
- # or Granite::Form::UndestroyableObject will be raised respectively.
49
- #
50
- # If performers was not defined in model, they cat be passed as
51
- # blocks to `save`, `update` and `destroy` methods:
52
- #
53
- # authos.save { REDIS.set(id, attributes.to_json) }
54
- # authos.update { REDIS.set(id, attributes.to_json) }
55
- # authos.destroy { REDIS.del(id) }
56
- #
57
- # Save and destroy processes acts almost the save way as
58
- # ActiveRecord's (with +persisted?+ and +destroyed?+ methods
59
- # affecting).
60
- #
61
- module Lifecycle
62
- extend ActiveSupport::Concern
63
-
64
- included do
65
- include Persistence
66
-
67
- class_attribute(*%i[save create update destroy].map { |action| "_#{action}_performer" })
68
- private(*%i[save create update destroy].map { |action| "_#{action}_performer=" })
69
- end
70
-
71
- module ClassMethods
72
- # <tt>define_<action></tt> methods define performers for lifecycle
73
- # actions. Every action block must return boolean result, which
74
- # would mean the action success. If action performed unsuccessfully
75
- # Granite::Form::ObjectNotSaved or Granite::Form::ObjectNotDestroyed will
76
- # be raised respectively in case of bang methods using.
77
- #
78
- # class Author
79
- # define_create { true }
80
- # end
81
- #
82
- # Author.new.save # => true
83
- # Author.new.save! # => true
84
- #
85
- # class Author
86
- # define_create { false }
87
- # end
88
- #
89
- # Author.new.save # => false
90
- # Author.new.save! # => Granite::Form::ObjectNotSaved
91
- #
92
- # Also performers blocks are executed in the instance context, but
93
- # instance also passed as argument
94
- #
95
- # define_update do |instance|
96
- # instance.attributes.to_json
97
- # end
98
- #
99
- # +define_create+ and +define_update+ performers has higher priority
100
- # than +define_save+.
101
- #
102
- # class Author
103
- # define_update { ... }
104
- # define_save { ... }
105
- # end
106
- #
107
- # author = Author.create # using define_save performer
108
- # author.update_attributes(...) # using define_update performer
109
- #
110
- %i[save create update destroy].each do |action|
111
- define_method "define_#{action}" do |&block|
112
- send("_#{action}_performer=", block)
113
- end
114
- end
115
-
116
- # Initializes new instance with attributes passed and calls +save+
117
- # on it. Returns instance in any case.
118
- #
119
- def create(*args)
120
- new(*args).tap(&:save)
121
- end
122
-
123
- # Initializes new instance with attributes passed and calls +save!+
124
- # on it. Returns instance in case of success and raises Granite::Form::ValidationError
125
- # or Granite::Form::ObjectNotSaved in case of validation or saving fail respectively.
126
- #
127
- def create!(*args)
128
- new(*args).tap(&:save!)
129
- end
130
- end
131
-
132
- # <tt>define_<action></tt> on instance level works the same
133
- # way as class <tt>define_<action></tt> methods, but defines
134
- # performers for instance only
135
- #
136
- # user.define_save do
137
- # REDIS.set(id, attributes.to_json)
138
- # end
139
- # user.save! # => will use instance-level performer
140
- #
141
- %i[save create update destroy].each do |action|
142
- define_method "define_#{action}" do |&block|
143
- send("_#{action}_performer=", block)
144
- end
145
- end
146
-
147
- # Assigns passed attributes and calls +save+
148
- # Returns true or false in case of successful or unsuccessful
149
- # saving respectively.
150
- #
151
- # author.update(name: 'Donald')
152
- #
153
- # If update performer is not defined with `define_update`
154
- # or `define_save`, it raises Granite::Form::UnsavableObject.
155
- # Also save performer block might be passed instead of in-class
156
- # performer definition:
157
- #
158
- # author.update(name: 'Donald') { REDIS.set(id, attributes.to_json) }
159
- #
160
- def update(attributes, &block)
161
- assign_attributes(attributes) && save(&block)
162
- end
163
-
164
- alias_method :update_attributes, :update
165
-
166
- # Assigns passed attributes and calls +save!+
167
- # Returns true in case of success and raises Granite::Form::ValidationError
168
- # or Granite::Form::ObjectNotSaved in case of validation or
169
- # saving fail respectively.
170
- #
171
- # author.update!(name: 'Donald')
172
- #
173
- # If update performer is not defined with `define_update`
174
- # or `define_save`, it raises Granite::Form::UnsavableObject.
175
- # Also save performer block might be passed instead of in-class
176
- # performer definition:
177
- #
178
- # author.update!(name: 'Donald') { REDIS.set(id, attributes.to_json) }
179
- #
180
- def update!(attributes, &block)
181
- assign_attributes(attributes) && save!(&block)
182
- end
183
-
184
- alias_method :update_attributes!, :update!
185
-
186
- # # Saves object by calling save performer defined with +define_save+,
187
- # +define_create+ or +define_update+ methods.
188
- # Returns true or false in case of successful
189
- # or unsuccessful saving respectively. Changes +persisted?+ to true
190
- #
191
- # author.save
192
- #
193
- # If save performer is not defined with `define_update` or
194
- # `define_create` or `define_save`, it raises Granite::Form::UnsavableObject.
195
- # Also save performer block might be passed instead of in-class
196
- # performer definition:
197
- #
198
- # author.save { REDIS.set(id, attributes.to_json) }
199
- #
200
- def save(_options = {}, &block)
201
- raise Granite::Form::UnsavableObject unless block || savable?
202
- valid? && save_object(&block)
203
- end
204
-
205
- # Saves object by calling save performer defined with +define_save+,
206
- # +define_create+ or +define_update+ methods.
207
- # Returns true in case of success and raises Granite::Form::ValidationError
208
- # or Granite::Form::ObjectNotSaved in case of validation or
209
- # saving fail respectively. Changes +persisted?+ to true
210
- #
211
- # author.save!
212
- #
213
- # If save performer is not defined with `define_update` or
214
- # `define_create` or `define_save`, it raises Granite::Form::UnsavableObject.
215
- # Also save performer block might be passed instead of in-class
216
- # performer definition:
217
- #
218
- # author.save! { REDIS.set(id, attributes.to_json) }
219
- #
220
- def save!(_options = {}, &block)
221
- raise Granite::Form::UnsavableObject unless block || savable?
222
- validate!
223
- save_object(&block) or raise Granite::Form::ObjectNotSaved
224
- end
225
-
226
- # Destroys object by calling the destroy performer.
227
- # Returns instance in any case. Changes +persisted?+
228
- # to false and +destroyed?+ to true in case of success.
229
- #
230
- # author.destroy
231
- #
232
- # If destroy performer is not defined with `define_destroy`,
233
- # it raises Granite::Form::UndestroyableObject.
234
- # Also destroy performer block might be passed instead of in-class
235
- # performer definition:
236
- #
237
- # author.destroy { REDIS.del(id) }
238
- #
239
- def destroy(&block)
240
- raise Granite::Form::UndestroyableObject unless block || destroyable?
241
- destroy_object(&block)
242
- self
243
- end
244
-
245
- # Destroys object by calling the destroy performer.
246
- # In case of success returns instance and changes +persisted?+
247
- # to false and +destroyed?+ to true.
248
- # Raises Granite::Form::ObjectNotDestroyed in case of fail.
249
- #
250
- # author.destroy!
251
- #
252
- # If destroy performer is not defined with `define_destroy`,
253
- # it raises Granite::Form::UndestroyableObject.
254
- # Also destroy performer block might be passed instead of in-class
255
- # performer definition:
256
- #
257
- # author.destroy! { REDIS.del(id) }
258
- #
259
- def destroy!(&block)
260
- raise Granite::Form::UndestroyableObject unless block || destroyable?
261
- destroy_object(&block) or raise Granite::Form::ObjectNotDestroyed
262
- self
263
- end
264
-
265
- private
266
-
267
- def savable?
268
- !!((persisted? ? _update_performer : _create_performer) || _save_performer)
269
- end
270
-
271
- def save_object(&block)
272
- apply_association_changes! if respond_to?(:apply_association_changes!)
273
- result = persisted? ? update_object(&block) : create_object(&block)
274
- mark_persisted! if result
275
- result
276
- end
277
-
278
- def create_object(&block)
279
- performer = block || _create_performer || _save_performer
280
- !!performer_exec(&performer)
281
- end
282
-
283
- def update_object(&block)
284
- performer = block || _update_performer || _save_performer
285
- !!performer_exec(&performer)
286
- end
287
-
288
- def destroyable?
289
- !!_destroy_performer
290
- end
291
-
292
- def destroy_object(&block)
293
- performer = block || _destroy_performer
294
- result = !!performer_exec(&performer)
295
- mark_destroyed! if result
296
- result
297
- end
298
-
299
- def performer_exec(&block)
300
- if block.arity == 1
301
- yield(self)
302
- else
303
- instance_exec(&block)
304
- end
305
- end
306
- end
307
- end
308
- end
309
- end