draftsman 0.3.7 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 194254f680cbf4f16b35d8752db70015373258af
4
- data.tar.gz: e098a3b022b8f4524b0475f13019402ff8e4b567
3
+ metadata.gz: cd9e61138b818bff3ff18a8f3039e2e890cd6f90
4
+ data.tar.gz: c84a08a47b0e0d19995a4c00c6a3a5de0ae48d61
5
5
  SHA512:
6
- metadata.gz: d91dd1b999f3e32d1fd53e2eed6426bedd09b9cf4e009dbdf14bec090d4b1860023e605d8911f0452fe36cdd906c8a7e65a5ee9c403be5b3ad90a871a46d8ffa
7
- data.tar.gz: cfad2c03e91eaaabac18e36cc98d83cf570beba41d8ca7aa55d076bce6e12965f08473dc24147cf15d0f9fc0b9c0b1deaf28980229e64fad1cada389a07ae6c7
6
+ metadata.gz: 200f68df8dbc6ab78eef9fad8dbfbdfcf33f5a57be1c4f5d3fdc8f8cb199254b20800f7170f37a99bb2d05aca071bd21704fafd8a78e42e653938fff7fd689d9
7
+ data.tar.gz: 613df4b0ad438fa2fb73fe3930d8201df1941e68640df7e42fb17c3f616b1a739519f16879bcf9b648aa3c3f92425cff1daf8404f96d44ea2edfe553ef7c7445
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.4.0 - April 5, 2016
4
+
5
+ - [@npafundi](https://github.com/npafundi)
6
+ [Implemented](https://github.com/liveeditor/draftsman/pull/20)
7
+ [#20](https://github.com/liveeditor/draftsman/pull/20) -
8
+ Adding callbacks for draft creation, update, and destroy
9
+ - [@chrisdpeters](https://github.com/chrisdpeters)
10
+ [Implemented](https://github.com/liveeditor/draftsman/commit/b3cecfa17f5cf296e7451cca56aeee41eac75f11)
11
+ [#16](https://github.com/liveeditor/draftsman/issues/16) -
12
+ Rename `draft_destroy` to `draft_destruction`
13
+ - [@defbyte](https://github.com/defbyte)
14
+ [Fixed](https://github.com/liveeditor/draftsman/pull/38)
15
+ [#39](https://github.com/liveeditor/draftsman/issues/39) -
16
+ Uh oh, ActiveSupport::DeprecationException error when running generated migrations
17
+ - [@chrisdpeters](https://github.com/chrisdpeters)
18
+ [Fixed](https://github.com/liveeditor/draftsman/commit/b0e328276e1e90ab877a6003f1d3165c7032267d)
19
+ [#40](https://github.com/liveeditor/draftsman/issues/40) -
20
+ Docs say publish! is available on the model instance, but it is not
21
+ - [@chrisdpeters](https://github.com/chrisdpeters)
22
+ [Fixed](https://github.com/liveeditor/draftsman/commit/bae427d2d38715da5b892888ff86d23bf5e39cb0)
23
+ [#17](https://github.com/liveeditor/draftsman/issues/17) -
24
+ Fix "open-ended dependency on rake" warning on gem build
25
+
3
26
  ## 0.3.7 - November 4, 2015
4
27
 
5
28
  - [@bdunham](https://github.com/bdunham)
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Draftsman v0.3.7 (alpha)
1
+ # Draftsman v0.4.0 (alpha)
2
2
 
3
3
  Draftsman is a Ruby gem that lets you create draft versions of your database records. If you're developing a system in
4
4
  need of simple drafts or a publishing approval queue, then Draftsman just might be what you need.
@@ -30,11 +30,13 @@ source: it's a nice clean example of a gem that hooks into Rails and Sinatra.
30
30
  - Allows you to store arbitrary model-level metadata with each draft (useful for filtering).
31
31
  - Allows you to store arbitrary controller-level information with each draft (e.g., remote IP, current account ID).
32
32
  - Only saves drafts when you explicitly tell it to via instance methods like `draft_creation`, `draft_update`, and
33
- `draft_destroy`.
33
+ `draft_destruction`.
34
34
  - Stores everything in a single database table by default (generates migration for you), or you can use separate tables
35
35
  for separate models.
36
36
  - Supports custom draft classes so different models' drafts can have different behavior.
37
37
  - Supports custom name for `draft` association.
38
+ - Supports `before`, `after`, and `around` callbacks on each draft persistence method, such as `before_draft_creation`
39
+ or `around_draft_update`.
38
40
  - Threadsafe.
39
41
 
40
42
  ## Compatibility
@@ -50,7 +52,7 @@ Works well with Rails, Sinatra, or any other application that depends on ActiveR
50
52
  Add Draftsman to your `Gemfile`.
51
53
 
52
54
  ```ruby
53
- gem 'draftsman', '0.3.7'
55
+ gem 'draftsman', '~> 0.4.0'
54
56
  ```
55
57
 
56
58
  Or if you want to grab the latest from `master`:
@@ -202,15 +204,12 @@ widget.draft_update
202
204
 
203
205
  # Trashes object and records a draft for a `destroy` event. (The `trashed_at` attribute must be set up on your model for
204
206
  # this to work.)
205
- widget.draft_destroy
207
+ widget.draft_destruction
206
208
 
207
209
  # Returns whether or not this item has been published at any point in its lifecycle.
208
210
  widget.published?
209
211
 
210
- # Sets `:published_at` attribute to now and saves to the database immediately.
211
- widget.publish!
212
-
213
- # Returns whether or not this item has been trashed via `draft_destroy`
212
+ # Returns whether or not this item has been trashed via `draft_destruction`.
214
213
  widget.trashed?
215
214
  ```
216
215
 
@@ -292,6 +291,31 @@ draft.draft_publication_dependencies
292
291
  draft.draft_reversion_dependencies
293
292
  ```
294
293
 
294
+ ### Callbacks
295
+
296
+ Draftsman supports callbacks for draft creation, update, and destroy. These callbacks can be defined in any model
297
+ that `has_drafts`.
298
+
299
+ Draft callbacks work similarly to ActiveRecord callbacks; pass any functions that you would like called
300
+ before/around/after a draft persistence method.
301
+
302
+ Available callbacks:
303
+ ```ruby
304
+ before_draft_creation # called before draft is created
305
+ around_draft_creation # called function must yield to `draft_creation`
306
+ after_draft_creation # called after draft is created
307
+
308
+ before_draft_update # called before draft is updated
309
+ around_draft_update # called function must yield to `draft_update`
310
+ after_draft_update # called after draft is updated
311
+
312
+ before_draft_destruction # called before draft is destroyed
313
+ around_draft_destruction # called function must yield to `draft_destruction`
314
+ after_draft_destruction # called after draft is destroyed
315
+ ```
316
+
317
+ Note that callbacks must be defined after your call to `has_drafts`.
318
+
295
319
  ## Basic Usage
296
320
 
297
321
  A basic `widgets` admin controller in Rails that saves all of the user's actions as drafts would look something like
@@ -349,8 +373,8 @@ class Admin::WidgetsController < Admin::BaseController
349
373
  end
350
374
 
351
375
  def destroy
352
- # Instead of calling `destroy`, you call `draft_destroy` to "trash" it as a draft
353
- @widget.draft_destroy
376
+ # Instead of calling `destroy`, you call `draft_destruction` to "trash" it as a draft
377
+ @widget.draft_destruction
354
378
  flash[:success] = 'The widget was moved to the trash.'
355
379
  redirect_to admin_widgets_path
356
380
  end
@@ -458,6 +482,30 @@ end
458
482
 
459
483
  ```
460
484
 
485
+ If you would like your `Widget` to have callbacks, it might look something like this:
486
+
487
+ ```ruby
488
+ class Widget < ActiveRecord::Base
489
+ has_drafts
490
+
491
+ before_draft_creation :say_hi
492
+ around_draft_update :surround_update
493
+
494
+ private
495
+
496
+ def say_hi
497
+ self.some_attr = 'Hi!'
498
+ end
499
+
500
+ def surround_update
501
+ # do something before update
502
+ yield
503
+ # do something after update
504
+ end
505
+ end
506
+ ```
507
+
508
+
461
509
  ## Differences from PaperTrail
462
510
 
463
511
  If you are familiar with the PaperTrail gem, some parts of the Draftsman gem will look very familiar.
@@ -465,8 +513,8 @@ If you are familiar with the PaperTrail gem, some parts of the Draftsman gem wil
465
513
  However, there are some differences:
466
514
 
467
515
  * PaperTrail hooks into ActiveRecord callbacks so that versions can be saved automatically with your normal CRUD
468
- operations (`save`, `create`, `update_attributes`, `destroy`, etc.). Draftsman requires that you explicitly call its
469
- own CRUD methods in order to save a draft (`draft_creation`, `draft_update`, and `draft_destroy`).
516
+ operations (`save`, `create`, `update`, `destroy`, etc.). Draftsman requires that you explicitly call its own
517
+ CRUD methods in order to save a draft (`draft_creation`, `draft_update`, and `draft_destruction`).
470
518
 
471
519
  * PaperTrail's `Version#object` column looks "backwards" and records the object's state _before_ the changes occurred.
472
520
  Because drafts record changes as they will look in the future, they must work differently. Draftsman's `Draft#object`
@@ -518,7 +566,7 @@ work on features or find bugs!
518
566
 
519
567
  ## License
520
568
 
521
- Copyright 2013-2014 Minimal Orange, LLC.
569
+ Copyright 2013-2016 Minimal Orange, LLC.
522
570
 
523
571
  Draftsman is released under the [MIT License][9].
524
572
 
data/draftsman.gemspec CHANGED
@@ -4,8 +4,8 @@ require 'draftsman/version'
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'draftsman'
6
6
  s.version = Draftsman::VERSION
7
- s.summary = "Create draft versions of your ActiveRecord models' data. Works with Ruby on Rails and Sinatra."
8
- s.description = s.summary
7
+ s.summary = 'Create draft versions of your database records.'
8
+ s.description = "Stores draft versions of your ActiveRecord models' data in a single table or split up into separate tables. Works with Ruby on Rails and Sinatra."
9
9
  s.homepage = 'https://github.com/liveeditor/draftsman'
10
10
  s.authors = ['Chris Peters']
11
11
  s.email = 'chris@minimalorange.com'
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
 
19
19
  s.add_dependency 'activerecord', ['>= 3.0', '< 5.0']
20
20
 
21
- s.add_development_dependency 'rake'
21
+ s.add_development_dependency 'rake', '~> 10.5'
22
22
  s.add_development_dependency 'railties', ['>= 3.0', '< 5.0']
23
23
  s.add_development_dependency 'sinatra', '~> 1.0'
24
24
  s.add_development_dependency 'rspec-rails', '3.2.1'
@@ -45,6 +45,10 @@ module Draftsman
45
45
  # any more ActiveRecord models than we need to.
46
46
  send :include, InstanceMethods
47
47
 
48
+ # Define before/around/after callbacks on each drafted model
49
+ send :extend, ActiveModel::Callbacks
50
+ define_model_callbacks :draft_creation, :draft_update, :draft_destruction, :draft_destroy
51
+
48
52
  class_attribute :draftsman_options
49
53
  self.draftsman_options = options.dup
50
54
 
@@ -194,33 +198,155 @@ module Draftsman
194
198
  # Creates object and records a draft for the object's creation. Returns `true` or `false` depending on whether or not
195
199
  # the objects passed validation and the save was successful.
196
200
  def draft_creation
197
- transaction do
198
- # We want to save the draft after create
199
- return false unless self.save
201
+ run_callbacks :draft_creation do
202
+ transaction do
203
+ # We want to save the draft after create
204
+ return false unless self.save
200
205
 
201
- data = {
202
- :item => self,
203
- :event => 'create',
204
- :whodunnit => Draftsman.whodunnit,
205
- :object => object_attrs_for_draft_record
206
- }
207
- data[:object_changes] = changes_for_draftsman(previous_changes: true) if track_object_changes_for_draft?
208
- data = merge_metadata_for_draft(data)
206
+ data = {
207
+ :item => self,
208
+ :event => 'create',
209
+ :whodunnit => Draftsman.whodunnit,
210
+ :object => object_attrs_for_draft_record
211
+ }
212
+ data[:object_changes] = changes_for_draftsman(previous_changes: true) if track_object_changes_for_draft?
213
+ data = merge_metadata_for_draft(data)
209
214
 
210
- send "build_#{self.class.draft_association_name}", data
215
+ send "build_#{self.class.draft_association_name}", data
211
216
 
212
- if send(self.class.draft_association_name).save
213
- write_attribute "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
214
- self.update_column "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
215
- return true
216
- else
217
- raise ActiveRecord::Rollback and return false
217
+ if send(self.class.draft_association_name).save
218
+ write_attribute "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
219
+ self.update_column "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
220
+ else
221
+ raise ActiveRecord::Rollback and return false
222
+ end
218
223
  end
219
224
  end
225
+ return true
220
226
  end
221
227
 
222
- # Trashes object and records a draft for a `destroy` event.
228
+ # DEPRECATED: Use `draft_destruction` instead.
223
229
  def draft_destroy
230
+ ActiveSupport::Deprecation.warn('`draft_destroy` is deprecated and will be removed from Draftsman 1.0. Use `draft_destruction` instead.')
231
+
232
+ run_callbacks :draft_destroy do
233
+ _draft_destruction
234
+ end
235
+ end
236
+
237
+ # Trashes object and records a draft for a `destroy` event.
238
+ def draft_destruction
239
+ run_callbacks :draft_destruction do
240
+ _draft_destruction
241
+ end
242
+ end
243
+
244
+ # Updates object and records a draft for an `update` event. If the draft is being updated to the object's original
245
+ # state, the draft is destroyed. Returns `true` or `false` depending on if the object passed validation and the save
246
+ # was successful.
247
+ def draft_update
248
+ run_callbacks :draft_update do
249
+ transaction do
250
+ save_only_columns_for_draft
251
+
252
+ # We want to save the draft before update
253
+ return false unless self.valid?
254
+
255
+ # If updating a creation draft, also update this item
256
+ if self.draft? && send(self.class.draft_association_name).create?
257
+ data = {
258
+ :item => self,
259
+ :whodunnit => Draftsman.whodunnit,
260
+ :object => object_attrs_for_draft_record
261
+ }
262
+
263
+ if track_object_changes_for_draft?
264
+ data[:object_changes] = changes_for_draftsman(changed_from: self.send(self.class.draft_association_name).changeset)
265
+ end
266
+ data = merge_metadata_for_draft(data)
267
+ send(self.class.draft_association_name).update_attributes data
268
+ self.save
269
+ # Destroy the draft if this record has changed back to the original record
270
+ elsif changed_to_original_for_draft?
271
+ nilified_draft = send(self.class.draft_association_name)
272
+ send "#{self.class.draft_association_name}_id=", nil
273
+ self.save
274
+ nilified_draft.destroy
275
+ # Save a draft if record is changed notably
276
+ elsif changed_notably_for_draft?
277
+ data = {
278
+ :item => self,
279
+ :whodunnit => Draftsman.whodunnit,
280
+ :object => object_attrs_for_draft_record
281
+ }
282
+ data = merge_metadata_for_draft(data)
283
+
284
+ # If there's already a draft, update it.
285
+ if send(self.class.draft_association_name).present?
286
+ data[:object_changes] = changes_for_draftsman if track_object_changes_for_draft?
287
+ send(self.class.draft_association_name).update_attributes data
288
+ update_skipped_attributes
289
+ # If there's not draft, create an update draft.
290
+ else
291
+ data[:event] = 'update'
292
+ data[:object_changes] = changes_for_draftsman if track_object_changes_for_draft?
293
+ send "build_#{self.class.draft_association_name}", data
294
+
295
+ if send(self.class.draft_association_name).save
296
+ update_column "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
297
+ update_skipped_attributes
298
+ else
299
+ raise ActiveRecord::Rollback and return false
300
+ end
301
+ end
302
+ # If record is a draft and not changed notably, then update the draft.
303
+ elsif self.draft?
304
+ data = {
305
+ :item => self,
306
+ :whodunnit => Draftsman.whodunnit,
307
+ :object => object_attrs_for_draft_record
308
+ }
309
+ data[:object_changes] = changes_for_draftsman(changed_from: @object.draft.changeset) if track_object_changes_for_draft?
310
+ data = merge_metadata_for_draft(data)
311
+ send(self.class.draft_association_name).update_attributes data
312
+ update_skipped_attributes
313
+ # Otherwise, just save the record
314
+ else
315
+ self.save
316
+ end
317
+ end
318
+ end
319
+ rescue Exception => e
320
+ false
321
+ end
322
+
323
+ # Returns serialized object representing this drafted item.
324
+ def object_attrs_for_draft_record(object = nil)
325
+ object ||= self
326
+
327
+ _attrs = object.attributes.except(*self.class.draftsman_options[:skip]).tap do |attributes|
328
+ self.class.serialize_attributes_for_draftsman attributes
329
+ end
330
+
331
+ self.class.draft_class.object_col_is_json? ? _attrs : Draftsman.serializer.dump(_attrs)
332
+ end
333
+
334
+ # Returns whether or not this item has been published at any point in its lifecycle.
335
+ def published?
336
+ self.published_at.present?
337
+ end
338
+
339
+ # Returns whether or not this item has been trashed
340
+ def trashed?
341
+ send(self.class.trashed_at_attribute_name).present?
342
+ end
343
+
344
+ private
345
+
346
+ # This is only abstracted away at this moment because of the
347
+ # `draft_destroy` deprecation. Move all of this logic back into
348
+ # `draft_destruction` after `draft_destroy is removed.`
349
+ def _draft_destruction
224
350
  transaction do
225
351
  data = {
226
352
  :item => self,
@@ -263,114 +389,13 @@ module Draftsman
263
389
  dependents = [dependents] if (dependents && association.macro == :has_one)
264
390
 
265
391
  dependents.each do |dependent|
266
- dependent.draft_destroy unless dependent.draft? && dependent.send(dependent.class.draft_association_name).destroy?
392
+ dependent.draft_destruction unless dependent.draft? && dependent.send(dependent.class.draft_association_name).destroy?
267
393
  end if dependents
268
394
  end
269
395
  end
270
396
  end
271
397
  end
272
398
 
273
- # Updates object and records a draft for an `update` event. If the draft is being updated to the object's original
274
- # state, the draft is destroyed. Returns `true` or `false` depending on if the object passed validation and the save
275
- # was successful.
276
- def draft_update
277
- transaction do
278
- save_only_columns_for_draft
279
-
280
- # We want to save the draft before update
281
- return false unless self.valid?
282
-
283
- # If updating a creation draft, also update this item
284
- if self.draft? && send(self.class.draft_association_name).create?
285
- data = {
286
- :item => self,
287
- :whodunnit => Draftsman.whodunnit,
288
- :object => object_attrs_for_draft_record
289
- }
290
-
291
- if track_object_changes_for_draft?
292
- data[:object_changes] = changes_for_draftsman(changed_from: self.send(self.class.draft_association_name).changeset)
293
- end
294
-
295
- data = merge_metadata_for_draft(data)
296
- send(self.class.draft_association_name).update_attributes data
297
- self.save
298
- # Destroy the draft if this record has changed back to the original record
299
- elsif changed_to_original_for_draft?
300
- nilified_draft = send(self.class.draft_association_name)
301
- send "#{self.class.draft_association_name}_id=", nil
302
- self.save
303
- nilified_draft.destroy
304
- # Save a draft if record is changed notably
305
- elsif changed_notably_for_draft?
306
- data = {
307
- :item => self,
308
- :whodunnit => Draftsman.whodunnit,
309
- :object => object_attrs_for_draft_record
310
- }
311
- data = merge_metadata_for_draft(data)
312
-
313
- # If there's already a draft, update it.
314
- if send(self.class.draft_association_name).present?
315
- data[:object_changes] = changes_for_draftsman if track_object_changes_for_draft?
316
- send(self.class.draft_association_name).update_attributes data
317
- update_skipped_attributes
318
- # If there's not draft, create an update draft.
319
- else
320
- data[:event] = 'update'
321
- data[:object_changes] = changes_for_draftsman if track_object_changes_for_draft?
322
- send "build_#{self.class.draft_association_name}", data
323
-
324
- if send(self.class.draft_association_name).save
325
- update_column "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
326
- update_skipped_attributes
327
- else
328
- raise ActiveRecord::Rollback and return false
329
- end
330
- end
331
- # If record is a draft and not changed notably, then update the draft.
332
- elsif self.draft?
333
- data = {
334
- :item => self,
335
- :whodunnit => Draftsman.whodunnit,
336
- :object => object_attrs_for_draft_record
337
- }
338
- data[:object_changes] = changes_for_draftsman(changed_from: @object.draft.changeset) if track_object_changes_for_draft?
339
- data = merge_metadata_for_draft(data)
340
- send(self.class.draft_association_name).update_attributes data
341
- update_skipped_attributes
342
- # Otherwise, just save the record
343
- else
344
- self.save
345
- end
346
- end
347
- rescue Exception => e
348
- false
349
- end
350
-
351
- # Returns serialized object representing this drafted item.
352
- def object_attrs_for_draft_record(object = nil)
353
- object ||= self
354
-
355
- _attrs = object.attributes.except(*self.class.draftsman_options[:skip]).tap do |attributes|
356
- self.class.serialize_attributes_for_draftsman attributes
357
- end
358
-
359
- self.class.draft_class.object_col_is_json? ? _attrs : Draftsman.serializer.dump(_attrs)
360
- end
361
-
362
- # Returns whether or not this item has been published at any point in its lifecycle.
363
- def published?
364
- self.published_at.present?
365
- end
366
-
367
- # Returns whether or not this item has been trashed
368
- def trashed?
369
- send(self.class.trashed_at_attribute_name).present?
370
- end
371
-
372
- private
373
-
374
399
  # Returns changes on this object, excluding attributes defined in the options for `:ignore` and `:skip`.
375
400
  def changed_and_not_ignored_for_draft(options = {})
376
401
  options[:previous_changes] ||= false
@@ -452,7 +477,7 @@ module Draftsman
452
477
  if self.class.draftsman_options[:only].any?
453
478
  only_changes = {}
454
479
  only_changed_attributes = self.changed - self.class.draftsman_options[:only]
455
-
480
+
456
481
  only_changed_attributes.each do |attribute|
457
482
  only_changes[attribute] = self.changes[attribute].last
458
483
  end
@@ -1,3 +1,3 @@
1
1
  module Draftsman
2
- VERSION = '0.3.7'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -7,7 +7,7 @@ class CreateDrafts < ActiveRecord::Migration
7
7
  t.string :whodunnit# :null => false
8
8
  t.text :object
9
9
  t.text :previous_draft
10
- t.timestamps
10
+ t.timestamps :null => false
11
11
  end
12
12
 
13
13
  change_table :drafts do |t|
@@ -7,7 +7,7 @@ class CreateDrafts < ActiveRecord::Migration
7
7
  t.string :whodunnit# :null => false
8
8
  t.json :object
9
9
  t.json :previous_draft
10
- t.timestamps
10
+ t.timestamps :null => false
11
11
  end
12
12
 
13
13
  change_table :drafts do |t|
@@ -14,7 +14,7 @@ class ApplicationController < ActionController::Base
14
14
  end
15
15
 
16
16
  def destroy
17
- Trashable.last.draft_destroy
17
+ Trashable.last.draft_destruction
18
18
  render nothing: true
19
19
  end
20
20
  end
@@ -0,0 +1,4 @@
1
+ class Enumable < ActiveRecord::Base
2
+ has_drafts
3
+ enum status: { active: 0, archived: 1 }
4
+ end
@@ -0,0 +1,66 @@
1
+ class Talkative < ActiveRecord::Base
2
+ has_drafts
3
+
4
+ # draft_creation callbacks
5
+ before_draft_creation :do_this_before_draft_creation
6
+ around_draft_creation :do_this_around_draft_creation
7
+ after_draft_creation :do_this_after_draft_creation
8
+
9
+ # draft_update callbacks
10
+ before_draft_update :do_this_before_draft_update
11
+ around_draft_update :do_this_around_draft_update
12
+ after_draft_update :do_this_after_draft_update
13
+
14
+ # # draft_destruction callbacks
15
+ before_draft_destruction :do_this_before_draft_destruction
16
+ around_draft_destruction :do_this_around_draft_destruction
17
+ after_draft_destruction :do_this_after_draft_destruction
18
+
19
+ private
20
+
21
+ def do_this_before_draft_creation
22
+ self.before_comment = "I changed before creation"
23
+ end
24
+
25
+ def do_this_around_draft_creation
26
+ self.around_early_comment = "I changed around creation (before yield)"
27
+ yield
28
+ self.around_late_comment = "I changed around creation (after yield)"
29
+ end
30
+
31
+ def do_this_after_draft_creation
32
+ self.after_comment = "I changed after creation"
33
+ end
34
+
35
+
36
+
37
+ def do_this_before_draft_update
38
+ self.before_comment = "I changed before update"
39
+ end
40
+
41
+ def do_this_around_draft_update
42
+ self.around_early_comment = "I changed around update (before yield)"
43
+ yield
44
+ self.around_late_comment = "I changed around update (after yield)"
45
+ end
46
+
47
+ def do_this_after_draft_update
48
+ self.after_comment = "I changed after update"
49
+ end
50
+
51
+
52
+
53
+ def do_this_before_draft_destruction
54
+ self.before_comment = "I changed before destroy"
55
+ end
56
+
57
+ def do_this_around_draft_destruction
58
+ self.around_early_comment = "I changed around destroy (before yield)"
59
+ yield
60
+ self.around_late_comment = "I changed around destroy (after yield)"
61
+ end
62
+
63
+ def do_this_after_draft_destruction
64
+ self.after_comment = "I changed after destroy"
65
+ end
66
+ end
@@ -14,7 +14,7 @@ Dummy::Application.configure do
14
14
  config.action_controller.perform_caching = false
15
15
 
16
16
  # Don't care if the mailer can't send
17
- config.action_mailer.raise_delivery_errors = false
17
+ # config.action_mailer.raise_delivery_errors = false
18
18
 
19
19
  # Print deprecation notices to the Rails logger
20
20
  config.active_support.deprecation = :log
@@ -0,0 +1,18 @@
1
+ class AddTalkativesTableToTests < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :talkatives, :force => true do |t|
4
+ t.string :before_comment
5
+ t.string :around_early_comment
6
+ t.string :around_late_comment
7
+ t.string :after_comment
8
+ t.references :draft
9
+ t.datetime :trashed_at
10
+ t.datetime :published_at
11
+ t.timestamps
12
+ end
13
+ end
14
+
15
+ def self.down
16
+ drop_table :talkatives
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ class CreateEnumables < ActiveRecord::Migration
2
+ def change
3
+ create_table :enumables do |t|
4
+ t.integer :status, :null => false
5
+ t.references :draft
6
+ t.timestamp :published_at
7
+ end
8
+ end
9
+ end