rails 3.2.22.2 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ ```