rails 3.2.22.2 → 4.2.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.
Files changed (216) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +85 -0
  3. data/guides/CHANGELOG.md +31 -0
  4. data/guides/Rakefile +79 -0
  5. data/guides/assets/images/akshaysurve.jpg +0 -0
  6. data/guides/assets/images/belongs_to.png +0 -0
  7. data/guides/assets/images/book_icon.gif +0 -0
  8. data/guides/assets/images/bullet.gif +0 -0
  9. data/guides/assets/images/chapters_icon.gif +0 -0
  10. data/guides/assets/images/check_bullet.gif +0 -0
  11. data/guides/assets/images/credits_pic_blank.gif +0 -0
  12. data/guides/assets/images/csrf.png +0 -0
  13. data/guides/assets/images/edge_badge.png +0 -0
  14. data/guides/assets/images/favicon.ico +0 -0
  15. data/guides/assets/images/feature_tile.gif +0 -0
  16. data/guides/assets/images/footer_tile.gif +0 -0
  17. data/guides/assets/images/fxn.png +0 -0
  18. data/guides/assets/images/getting_started/article_with_comments.png +0 -0
  19. data/guides/assets/images/getting_started/challenge.png +0 -0
  20. data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
  21. data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
  22. data/guides/assets/images/getting_started/form_with_errors.png +0 -0
  23. data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
  24. data/guides/assets/images/getting_started/new_article.png +0 -0
  25. data/guides/assets/images/getting_started/rails_welcome.png +0 -0
  26. data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
  27. data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
  28. data/guides/assets/images/getting_started/show_action_for_articles.png +0 -0
  29. data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
  30. data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
  31. data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
  32. data/guides/assets/images/grey_bullet.gif +0 -0
  33. data/guides/assets/images/habtm.png +0 -0
  34. data/guides/assets/images/has_many.png +0 -0
  35. data/guides/assets/images/has_many_through.png +0 -0
  36. data/guides/assets/images/has_one.png +0 -0
  37. data/guides/assets/images/has_one_through.png +0 -0
  38. data/guides/assets/images/header_backdrop.png +0 -0
  39. data/guides/assets/images/header_tile.gif +0 -0
  40. data/guides/assets/images/i18n/demo_html_safe.png +0 -0
  41. data/guides/assets/images/i18n/demo_localized_pirate.png +0 -0
  42. data/guides/assets/images/i18n/demo_translated_en.png +0 -0
  43. data/guides/assets/images/i18n/demo_translated_pirate.png +0 -0
  44. data/guides/assets/images/i18n/demo_translation_missing.png +0 -0
  45. data/guides/assets/images/i18n/demo_untranslated.png +0 -0
  46. data/guides/assets/images/icons/README +5 -0
  47. data/guides/assets/images/icons/callouts/1.png +0 -0
  48. data/guides/assets/images/icons/callouts/10.png +0 -0
  49. data/guides/assets/images/icons/callouts/11.png +0 -0
  50. data/guides/assets/images/icons/callouts/12.png +0 -0
  51. data/guides/assets/images/icons/callouts/13.png +0 -0
  52. data/guides/assets/images/icons/callouts/14.png +0 -0
  53. data/guides/assets/images/icons/callouts/15.png +0 -0
  54. data/guides/assets/images/icons/callouts/2.png +0 -0
  55. data/guides/assets/images/icons/callouts/3.png +0 -0
  56. data/guides/assets/images/icons/callouts/4.png +0 -0
  57. data/guides/assets/images/icons/callouts/5.png +0 -0
  58. data/guides/assets/images/icons/callouts/6.png +0 -0
  59. data/guides/assets/images/icons/callouts/7.png +0 -0
  60. data/guides/assets/images/icons/callouts/8.png +0 -0
  61. data/guides/assets/images/icons/callouts/9.png +0 -0
  62. data/guides/assets/images/icons/caution.png +0 -0
  63. data/guides/assets/images/icons/example.png +0 -0
  64. data/guides/assets/images/icons/home.png +0 -0
  65. data/guides/assets/images/icons/important.png +0 -0
  66. data/guides/assets/images/icons/next.png +0 -0
  67. data/guides/assets/images/icons/note.png +0 -0
  68. data/guides/assets/images/icons/prev.png +0 -0
  69. data/guides/assets/images/icons/tip.png +0 -0
  70. data/guides/assets/images/icons/up.png +0 -0
  71. data/guides/assets/images/icons/warning.png +0 -0
  72. data/guides/assets/images/nav_arrow.gif +0 -0
  73. data/guides/assets/images/oscardelben.jpg +0 -0
  74. data/guides/assets/images/polymorphic.png +0 -0
  75. data/guides/assets/images/radar.png +0 -0
  76. data/guides/assets/images/rails4_features.png +0 -0
  77. data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
  78. data/guides/assets/images/rails_guides_logo.gif +0 -0
  79. data/guides/assets/images/rails_logo_remix.gif +0 -0
  80. data/guides/assets/images/session_fixation.png +0 -0
  81. data/guides/assets/images/tab_grey.gif +0 -0
  82. data/guides/assets/images/tab_info.gif +0 -0
  83. data/guides/assets/images/tab_note.gif +0 -0
  84. data/guides/assets/images/tab_red.gif +0 -0
  85. data/guides/assets/images/tab_yellow.gif +0 -0
  86. data/guides/assets/images/tab_yellow.png +0 -0
  87. data/guides/assets/images/vijaydev.jpg +0 -0
  88. data/guides/assets/javascripts/guides.js +59 -0
  89. data/guides/assets/javascripts/jquery.min.js +4 -0
  90. data/guides/assets/javascripts/responsive-tables.js +43 -0
  91. data/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js +59 -0
  92. data/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js +75 -0
  93. data/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js +59 -0
  94. data/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js +65 -0
  95. data/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js +100 -0
  96. data/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js +97 -0
  97. data/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js +91 -0
  98. data/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js +55 -0
  99. data/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js +41 -0
  100. data/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js +52 -0
  101. data/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js +67 -0
  102. data/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js +52 -0
  103. data/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js +57 -0
  104. data/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js +58 -0
  105. data/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js +72 -0
  106. data/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js +88 -0
  107. data/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js +33 -0
  108. data/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js +74 -0
  109. data/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js +64 -0
  110. data/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js +55 -0
  111. data/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js +94 -0
  112. data/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js +51 -0
  113. data/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js +66 -0
  114. data/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js +56 -0
  115. data/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js +69 -0
  116. data/guides/assets/javascripts/syntaxhighlighter/shCore.js +17 -0
  117. data/guides/assets/stylesheets/fixes.css +16 -0
  118. data/guides/assets/stylesheets/kindle.css +11 -0
  119. data/guides/assets/stylesheets/main.css +713 -0
  120. data/guides/assets/stylesheets/print.css +52 -0
  121. data/guides/assets/stylesheets/reset.css +43 -0
  122. data/guides/assets/stylesheets/responsive-tables.css +50 -0
  123. data/guides/assets/stylesheets/style.css +13 -0
  124. data/guides/assets/stylesheets/syntaxhighlighter/shCore.css +226 -0
  125. data/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css +328 -0
  126. data/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css +331 -0
  127. data/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css +339 -0
  128. data/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css +324 -0
  129. data/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +328 -0
  130. data/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css +324 -0
  131. data/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css +324 -0
  132. data/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css +324 -0
  133. data/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css +117 -0
  134. data/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css +120 -0
  135. data/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css +128 -0
  136. data/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css +113 -0
  137. data/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +117 -0
  138. data/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css +113 -0
  139. data/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css +113 -0
  140. data/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css +113 -0
  141. data/guides/assets/stylesheets/syntaxhighlighter/shThemeRailsGuides.css +116 -0
  142. data/guides/bug_report_templates/action_controller_gem.rb +47 -0
  143. data/guides/bug_report_templates/action_controller_master.rb +54 -0
  144. data/guides/bug_report_templates/active_record_gem.rb +40 -0
  145. data/guides/bug_report_templates/active_record_master.rb +49 -0
  146. data/guides/rails_guides/generator.rb +248 -0
  147. data/guides/rails_guides/helpers.rb +53 -0
  148. data/guides/rails_guides/indexer.rb +68 -0
  149. data/guides/rails_guides/kindle.rb +119 -0
  150. data/guides/rails_guides/levenshtein.rb +39 -0
  151. data/guides/rails_guides/markdown/renderer.rb +82 -0
  152. data/guides/rails_guides/markdown.rb +167 -0
  153. data/guides/rails_guides.rb +63 -0
  154. data/guides/source/2_2_release_notes.md +435 -0
  155. data/guides/source/2_3_release_notes.md +621 -0
  156. data/guides/source/3_0_release_notes.md +611 -0
  157. data/guides/source/3_1_release_notes.md +559 -0
  158. data/guides/source/3_2_release_notes.md +568 -0
  159. data/guides/source/4_0_release_notes.md +279 -0
  160. data/guides/source/4_1_release_notes.md +730 -0
  161. data/guides/source/4_2_release_notes.md +850 -0
  162. data/guides/source/_license.html.erb +2 -0
  163. data/guides/source/_welcome.html.erb +19 -0
  164. data/guides/source/action_controller_overview.md +1249 -0
  165. data/guides/source/action_mailer_basics.md +752 -0
  166. data/guides/source/action_view_overview.md +1620 -0
  167. data/guides/source/active_job_basics.md +318 -0
  168. data/guides/source/active_model_basics.md +554 -0
  169. data/guides/source/active_record_basics.md +374 -0
  170. data/guides/source/active_record_callbacks.md +413 -0
  171. data/guides/source/active_record_migrations.md +1018 -0
  172. data/guides/source/active_record_postgresql.md +433 -0
  173. data/guides/source/active_record_querying.md +1783 -0
  174. data/guides/source/active_record_validations.md +1178 -0
  175. data/guides/source/active_support_core_extensions.md +3904 -0
  176. data/guides/source/active_support_instrumentation.md +499 -0
  177. data/guides/source/api_documentation_guidelines.md +361 -0
  178. data/guides/source/asset_pipeline.md +1360 -0
  179. data/guides/source/association_basics.md +2236 -0
  180. data/guides/source/caching_with_rails.md +379 -0
  181. data/guides/source/command_line.md +625 -0
  182. data/guides/source/configuring.md +1045 -0
  183. data/guides/source/constant_autoloading_and_reloading.md +1297 -0
  184. data/guides/source/contributing_to_ruby_on_rails.md +624 -0
  185. data/guides/source/credits.html.erb +80 -0
  186. data/guides/source/debugging_rails_applications.md +861 -0
  187. data/guides/source/development_dependencies_install.md +289 -0
  188. data/guides/source/documents.yaml +205 -0
  189. data/guides/source/engines.md +1412 -0
  190. data/guides/source/form_helpers.md +1024 -0
  191. data/guides/source/generators.md +676 -0
  192. data/guides/source/getting_started.md +2085 -0
  193. data/guides/source/i18n.md +1086 -0
  194. data/guides/source/index.html.erb +28 -0
  195. data/guides/source/initialization.md +704 -0
  196. data/guides/source/kindle/copyright.html.erb +1 -0
  197. data/guides/source/kindle/layout.html.erb +27 -0
  198. data/guides/source/kindle/rails_guides.opf.erb +52 -0
  199. data/guides/source/kindle/toc.html.erb +24 -0
  200. data/guides/source/kindle/toc.ncx.erb +64 -0
  201. data/guides/source/kindle/welcome.html.erb +5 -0
  202. data/guides/source/layout.html.erb +143 -0
  203. data/guides/source/layouts_and_rendering.md +1227 -0
  204. data/guides/source/maintenance_policy.md +78 -0
  205. data/guides/source/nested_model_forms.md +228 -0
  206. data/guides/source/plugins.md +444 -0
  207. data/guides/source/rails_application_templates.md +266 -0
  208. data/guides/source/rails_on_rack.md +336 -0
  209. data/guides/source/routing.md +1141 -0
  210. data/guides/source/ruby_on_rails_guides_guidelines.md +127 -0
  211. data/guides/source/security.md +1024 -0
  212. data/guides/source/testing.md +1123 -0
  213. data/guides/source/upgrading_ruby_on_rails.md +1154 -0
  214. data/guides/source/working_with_javascript_in_rails.md +407 -0
  215. data/guides/w3c_validator.rb +97 -0
  216. metadata +290 -44
@@ -0,0 +1,318 @@
1
+ Active Job Basics
2
+ =================
3
+
4
+ This guide provides you with all you need to get started in creating,
5
+ enqueueing and executing background jobs.
6
+
7
+ After reading this guide, you will know:
8
+
9
+ * How to create jobs.
10
+ * How to enqueue jobs.
11
+ * How to run jobs in the background.
12
+ * How to send emails from your application async.
13
+
14
+ --------------------------------------------------------------------------------
15
+
16
+
17
+ Introduction
18
+ ------------
19
+
20
+ Active Job is a framework for declaring jobs and making them run on a variety
21
+ of queueing backends. These jobs can be everything from regularly scheduled
22
+ clean-ups, to billing charges, to mailings. Anything that can be chopped up
23
+ into small units of work and run in parallel, really.
24
+
25
+
26
+ The Purpose of Active Job
27
+ -----------------------------
28
+ The main point is to ensure that all Rails apps will have a job infrastructure
29
+ in place, even if it's in the form of an "immediate runner". We can then have
30
+ framework features and other gems build on top of that, without having to
31
+ worry about API differences between various job runners such as Delayed Job
32
+ and Resque. Picking your queuing backend becomes more of an operational concern,
33
+ then. And you'll be able to switch between them without having to rewrite your jobs.
34
+
35
+
36
+ Creating a Job
37
+ --------------
38
+
39
+ This section will provide a step-by-step guide to creating a job and enqueuing it.
40
+
41
+ ### Create the Job
42
+
43
+ Active Job provides a Rails generator to create jobs. The following will create a
44
+ job in `app/jobs` (with an attached test case under `test/jobs`):
45
+
46
+ ```bash
47
+ $ bin/rails generate job guests_cleanup
48
+ invoke test_unit
49
+ create test/jobs/guests_cleanup_job_test.rb
50
+ create app/jobs/guests_cleanup_job.rb
51
+ ```
52
+
53
+ You can also create a job that will run on a specific queue:
54
+
55
+ ```bash
56
+ $ bin/rails generate job guests_cleanup --queue urgent
57
+ ```
58
+
59
+ If you don't want to use a generator, you could create your own file inside of
60
+ `app/jobs`, just make sure that it inherits from `ActiveJob::Base`.
61
+
62
+ Here's what a job looks like:
63
+
64
+ ```ruby
65
+ class GuestsCleanupJob < ActiveJob::Base
66
+ queue_as :default
67
+
68
+ def perform(*args)
69
+ # Do something later
70
+ end
71
+ end
72
+ ```
73
+
74
+ ### Enqueue the Job
75
+
76
+ Enqueue a job like so:
77
+
78
+ ```ruby
79
+ # Enqueue a job to be performed as soon the queueing system is free.
80
+ MyJob.perform_later record
81
+ ```
82
+
83
+ ```ruby
84
+ # Enqueue a job to be performed tomorrow at noon.
85
+ MyJob.set(wait_until: Date.tomorrow.noon).perform_later(record)
86
+ ```
87
+
88
+ ```ruby
89
+ # Enqueue a job to be performed 1 week from now.
90
+ MyJob.set(wait: 1.week).perform_later(record)
91
+ ```
92
+
93
+ That's it!
94
+
95
+
96
+ Job Execution
97
+ -------------
98
+
99
+ If no adapter is set, the job is immediately executed.
100
+
101
+ ### Backends
102
+
103
+ Active Job has built-in adapters for multiple queueing backends (Sidekiq,
104
+ Resque, Delayed Job and others). To get an up-to-date list of the adapters
105
+ see the API Documentation for [ActiveJob::QueueAdapters](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).
106
+
107
+ ### Setting the Backend
108
+
109
+ You can easily set your queueing backend:
110
+
111
+ ```ruby
112
+ # config/application.rb
113
+ module YourApp
114
+ class Application < Rails::Application
115
+ # Be sure to have the adapter's gem in your Gemfile and follow
116
+ # the adapter's specific installation and deployment instructions.
117
+ config.active_job.queue_adapter = :sidekiq
118
+ end
119
+ end
120
+ ```
121
+
122
+
123
+ Queues
124
+ ------
125
+
126
+ Most of the adapters support multiple queues. With Active Job you can schedule
127
+ the job to run on a specific queue:
128
+
129
+ ```ruby
130
+ class GuestsCleanupJob < ActiveJob::Base
131
+ queue_as :low_priority
132
+ #....
133
+ end
134
+ ```
135
+
136
+ You can prefix the queue name for all your jobs using
137
+ `config.active_job.queue_name_prefix` in `application.rb`:
138
+
139
+ ```ruby
140
+ # config/application.rb
141
+ module YourApp
142
+ class Application < Rails::Application
143
+ config.active_job.queue_name_prefix = Rails.env
144
+ end
145
+ end
146
+
147
+ # app/jobs/guests_cleanup.rb
148
+ class GuestsCleanupJob < ActiveJob::Base
149
+ queue_as :low_priority
150
+ #....
151
+ end
152
+
153
+ # Now your job will run on queue production_low_priority on your
154
+ # production environment and on staging_low_priority on your staging
155
+ # environment
156
+ ```
157
+
158
+ The default queue name prefix delimiter is '\_'. This can be changed by setting
159
+ `config.active_job.queue_name_delimiter` in `application.rb`:
160
+
161
+ ```ruby
162
+ # config/application.rb
163
+ module YourApp
164
+ class Application < Rails::Application
165
+ config.active_job.queue_name_prefix = Rails.env
166
+ config.active_job.queue_name_delimiter = '.'
167
+ end
168
+ end
169
+
170
+ # app/jobs/guests_cleanup.rb
171
+ class GuestsCleanupJob < ActiveJob::Base
172
+ queue_as :low_priority
173
+ #....
174
+ end
175
+
176
+ # Now your job will run on queue production.low_priority on your
177
+ # production environment and on staging.low_priority on your staging
178
+ # environment
179
+ ```
180
+
181
+ If you want more control on what queue a job will be run you can pass a `:queue`
182
+ option to `#set`:
183
+
184
+ ```ruby
185
+ MyJob.set(queue: :another_queue).perform_later(record)
186
+ ```
187
+
188
+ To control the queue from the job level you can pass a block to `#queue_as`. The
189
+ block will be executed in the job context (so you can access `self.arguments`)
190
+ and you must return the queue name:
191
+
192
+ ```ruby
193
+ class ProcessVideoJob < ActiveJob::Base
194
+ queue_as do
195
+ video = self.arguments.first
196
+ if video.owner.premium?
197
+ :premium_videojobs
198
+ else
199
+ :videojobs
200
+ end
201
+ end
202
+
203
+ def perform(video)
204
+ # do process video
205
+ end
206
+ end
207
+
208
+ ProcessVideoJob.perform_later(Video.last)
209
+ ```
210
+
211
+ NOTE: Make sure your queueing backend "listens" on your queue name. For some
212
+ backends you need to specify the queues to listen to.
213
+
214
+
215
+ Callbacks
216
+ ---------
217
+
218
+ Active Job provides hooks during the lifecycle of a job. Callbacks allow you to
219
+ trigger logic during the lifecycle of a job.
220
+
221
+ ### Available callbacks
222
+
223
+ * `before_enqueue`
224
+ * `around_enqueue`
225
+ * `after_enqueue`
226
+ * `before_perform`
227
+ * `around_perform`
228
+ * `after_perform`
229
+
230
+ ### Usage
231
+
232
+ ```ruby
233
+ class GuestsCleanupJob < ActiveJob::Base
234
+ queue_as :default
235
+
236
+ before_enqueue do |job|
237
+ # do something with the job instance
238
+ end
239
+
240
+ around_perform do |job, block|
241
+ # do something before perform
242
+ block.call
243
+ # do something after perform
244
+ end
245
+
246
+ def perform
247
+ # Do something later
248
+ end
249
+ end
250
+ ```
251
+
252
+
253
+ Action Mailer
254
+ ------------
255
+
256
+ One of the most common jobs in a modern web application is sending emails outside
257
+ of the request-response cycle, so the user doesn't have to wait on it. Active Job
258
+ is integrated with Action Mailer so you can easily send emails asynchronously:
259
+
260
+ ```ruby
261
+ # If you want to send the email now use #deliver_now
262
+ UserMailer.welcome(@user).deliver_now
263
+
264
+ # If you want to send the email through Active Job use #deliver_later
265
+ UserMailer.welcome(@user).deliver_later
266
+ ```
267
+
268
+
269
+ GlobalID
270
+ --------
271
+
272
+ Active Job supports GlobalID for parameters. This makes it possible to pass live
273
+ Active Record objects to your job instead of class/id pairs, which you then have
274
+ to manually deserialize. Before, jobs would look like this:
275
+
276
+ ```ruby
277
+ class TrashableCleanupJob < ActiveJob::Base
278
+ def perform(trashable_class, trashable_id, depth)
279
+ trashable = trashable_class.constantize.find(trashable_id)
280
+ trashable.cleanup(depth)
281
+ end
282
+ end
283
+ ```
284
+
285
+ Now you can simply do:
286
+
287
+ ```ruby
288
+ class TrashableCleanupJob < ActiveJob::Base
289
+ def perform(trashable, depth)
290
+ trashable.cleanup(depth)
291
+ end
292
+ end
293
+ ```
294
+
295
+ This works with any class that mixes in `GlobalID::Identification`, which
296
+ by default has been mixed into Active Model classes.
297
+
298
+
299
+ Exceptions
300
+ ----------
301
+
302
+ Active Job provides a way to catch exceptions raised during the execution of the
303
+ job:
304
+
305
+ ```ruby
306
+
307
+ class GuestsCleanupJob < ActiveJob::Base
308
+ queue_as :default
309
+
310
+ rescue_from(ActiveRecord::RecordNotFound) do |exception|
311
+ # do something with the exception
312
+ end
313
+
314
+ def perform
315
+ # Do something later
316
+ end
317
+ end
318
+ ```