sequel 5.83.0 → 5.84.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sequel/adapters/shared/sqlite.rb +3 -1
  3. data/lib/sequel/database/connecting.rb +1 -1
  4. data/lib/sequel/database/misc.rb +8 -3
  5. data/lib/sequel/database/schema_methods.rb +2 -0
  6. data/lib/sequel/extensions/pg_json_ops.rb +328 -1
  7. data/lib/sequel/sql.rb +8 -5
  8. data/lib/sequel/version.rb +1 -1
  9. metadata +2 -236
  10. data/CHANGELOG +0 -1393
  11. data/README.rdoc +0 -936
  12. data/doc/advanced_associations.rdoc +0 -884
  13. data/doc/association_basics.rdoc +0 -1859
  14. data/doc/bin_sequel.rdoc +0 -146
  15. data/doc/cheat_sheet.rdoc +0 -255
  16. data/doc/code_order.rdoc +0 -104
  17. data/doc/core_extensions.rdoc +0 -405
  18. data/doc/dataset_basics.rdoc +0 -96
  19. data/doc/dataset_filtering.rdoc +0 -222
  20. data/doc/extensions.rdoc +0 -77
  21. data/doc/fork_safety.rdoc +0 -84
  22. data/doc/mass_assignment.rdoc +0 -98
  23. data/doc/migration.rdoc +0 -660
  24. data/doc/model_dataset_method_design.rdoc +0 -129
  25. data/doc/model_hooks.rdoc +0 -254
  26. data/doc/model_plugins.rdoc +0 -270
  27. data/doc/mssql_stored_procedures.rdoc +0 -43
  28. data/doc/object_model.rdoc +0 -563
  29. data/doc/opening_databases.rdoc +0 -439
  30. data/doc/postgresql.rdoc +0 -611
  31. data/doc/prepared_statements.rdoc +0 -144
  32. data/doc/querying.rdoc +0 -1070
  33. data/doc/reflection.rdoc +0 -120
  34. data/doc/release_notes/5.0.0.txt +0 -159
  35. data/doc/release_notes/5.1.0.txt +0 -31
  36. data/doc/release_notes/5.10.0.txt +0 -84
  37. data/doc/release_notes/5.11.0.txt +0 -83
  38. data/doc/release_notes/5.12.0.txt +0 -141
  39. data/doc/release_notes/5.13.0.txt +0 -27
  40. data/doc/release_notes/5.14.0.txt +0 -63
  41. data/doc/release_notes/5.15.0.txt +0 -39
  42. data/doc/release_notes/5.16.0.txt +0 -110
  43. data/doc/release_notes/5.17.0.txt +0 -31
  44. data/doc/release_notes/5.18.0.txt +0 -69
  45. data/doc/release_notes/5.19.0.txt +0 -28
  46. data/doc/release_notes/5.2.0.txt +0 -33
  47. data/doc/release_notes/5.20.0.txt +0 -89
  48. data/doc/release_notes/5.21.0.txt +0 -87
  49. data/doc/release_notes/5.22.0.txt +0 -48
  50. data/doc/release_notes/5.23.0.txt +0 -56
  51. data/doc/release_notes/5.24.0.txt +0 -56
  52. data/doc/release_notes/5.25.0.txt +0 -32
  53. data/doc/release_notes/5.26.0.txt +0 -35
  54. data/doc/release_notes/5.27.0.txt +0 -21
  55. data/doc/release_notes/5.28.0.txt +0 -16
  56. data/doc/release_notes/5.29.0.txt +0 -22
  57. data/doc/release_notes/5.3.0.txt +0 -121
  58. data/doc/release_notes/5.30.0.txt +0 -20
  59. data/doc/release_notes/5.31.0.txt +0 -148
  60. data/doc/release_notes/5.32.0.txt +0 -46
  61. data/doc/release_notes/5.33.0.txt +0 -24
  62. data/doc/release_notes/5.34.0.txt +0 -40
  63. data/doc/release_notes/5.35.0.txt +0 -56
  64. data/doc/release_notes/5.36.0.txt +0 -60
  65. data/doc/release_notes/5.37.0.txt +0 -30
  66. data/doc/release_notes/5.38.0.txt +0 -28
  67. data/doc/release_notes/5.39.0.txt +0 -19
  68. data/doc/release_notes/5.4.0.txt +0 -80
  69. data/doc/release_notes/5.40.0.txt +0 -40
  70. data/doc/release_notes/5.41.0.txt +0 -25
  71. data/doc/release_notes/5.42.0.txt +0 -136
  72. data/doc/release_notes/5.43.0.txt +0 -98
  73. data/doc/release_notes/5.44.0.txt +0 -32
  74. data/doc/release_notes/5.45.0.txt +0 -34
  75. data/doc/release_notes/5.46.0.txt +0 -87
  76. data/doc/release_notes/5.47.0.txt +0 -59
  77. data/doc/release_notes/5.48.0.txt +0 -14
  78. data/doc/release_notes/5.49.0.txt +0 -59
  79. data/doc/release_notes/5.5.0.txt +0 -61
  80. data/doc/release_notes/5.50.0.txt +0 -78
  81. data/doc/release_notes/5.51.0.txt +0 -47
  82. data/doc/release_notes/5.52.0.txt +0 -87
  83. data/doc/release_notes/5.53.0.txt +0 -23
  84. data/doc/release_notes/5.54.0.txt +0 -27
  85. data/doc/release_notes/5.55.0.txt +0 -21
  86. data/doc/release_notes/5.56.0.txt +0 -51
  87. data/doc/release_notes/5.57.0.txt +0 -23
  88. data/doc/release_notes/5.58.0.txt +0 -31
  89. data/doc/release_notes/5.59.0.txt +0 -73
  90. data/doc/release_notes/5.6.0.txt +0 -31
  91. data/doc/release_notes/5.60.0.txt +0 -22
  92. data/doc/release_notes/5.61.0.txt +0 -43
  93. data/doc/release_notes/5.62.0.txt +0 -132
  94. data/doc/release_notes/5.63.0.txt +0 -33
  95. data/doc/release_notes/5.64.0.txt +0 -50
  96. data/doc/release_notes/5.65.0.txt +0 -21
  97. data/doc/release_notes/5.66.0.txt +0 -24
  98. data/doc/release_notes/5.67.0.txt +0 -32
  99. data/doc/release_notes/5.68.0.txt +0 -61
  100. data/doc/release_notes/5.69.0.txt +0 -26
  101. data/doc/release_notes/5.7.0.txt +0 -108
  102. data/doc/release_notes/5.70.0.txt +0 -35
  103. data/doc/release_notes/5.71.0.txt +0 -21
  104. data/doc/release_notes/5.72.0.txt +0 -33
  105. data/doc/release_notes/5.73.0.txt +0 -66
  106. data/doc/release_notes/5.74.0.txt +0 -45
  107. data/doc/release_notes/5.75.0.txt +0 -35
  108. data/doc/release_notes/5.76.0.txt +0 -86
  109. data/doc/release_notes/5.77.0.txt +0 -63
  110. data/doc/release_notes/5.78.0.txt +0 -67
  111. data/doc/release_notes/5.79.0.txt +0 -28
  112. data/doc/release_notes/5.8.0.txt +0 -170
  113. data/doc/release_notes/5.80.0.txt +0 -40
  114. data/doc/release_notes/5.81.0.txt +0 -31
  115. data/doc/release_notes/5.82.0.txt +0 -61
  116. data/doc/release_notes/5.83.0.txt +0 -56
  117. data/doc/release_notes/5.9.0.txt +0 -99
  118. data/doc/schema_modification.rdoc +0 -679
  119. data/doc/security.rdoc +0 -443
  120. data/doc/sharding.rdoc +0 -286
  121. data/doc/sql.rdoc +0 -648
  122. data/doc/testing.rdoc +0 -204
  123. data/doc/thread_safety.rdoc +0 -15
  124. data/doc/transactions.rdoc +0 -250
  125. data/doc/validations.rdoc +0 -558
  126. data/doc/virtual_rows.rdoc +0 -265
@@ -1,1859 +0,0 @@
1
- = Association Basics
2
-
3
- This guide is based on http://guides.rubyonrails.org/association_basics.html
4
-
5
- == Why Associations?
6
-
7
- Associations exist to simplify code that deals with related rows in separate
8
- database tables. Without associations, if you had classes such as:
9
-
10
- class Artist < Sequel::Model
11
- end
12
-
13
- class Album < Sequel::Model
14
- end
15
-
16
- And you wanted to get all of the albums for a given artist (assuming each
17
- album was associated with only one artist):
18
-
19
- Album.where(artist_id: @artist.id).all
20
-
21
- Or maybe you want to add an album for a given artist:
22
-
23
- Album.create(artist_id: @artist.id, name: 'RF')
24
-
25
- With associations, you can make the above code simpler, by setting up associations
26
- between the two models:
27
-
28
- class Artist < Sequel::Model
29
- one_to_many :albums
30
- end
31
-
32
- class Album < Sequel::Model
33
- many_to_one :artist
34
- end
35
-
36
- Then, the code to retrieve albums related to the artist is simpler:
37
-
38
- @artist.albums
39
-
40
- As is the code to add a related album to an artist:
41
-
42
- @artist.add_album(name: 'RF')
43
-
44
- It also makes it easier to create queries that use joins based on the association:
45
-
46
- Artist.association_join(:albums)
47
- # SELECT * FROM artists
48
- # INNER JOIN albums ON (albums.artist_id = artists.id)
49
-
50
- == The Types of Associations
51
-
52
- Sequel has five different association types built in:
53
-
54
- * many_to_one
55
- * one_to_many
56
- * one_to_one
57
- * many_to_many
58
- * one_through_one
59
-
60
- It ships with additional association types via plugins.
61
-
62
- === many_to_one
63
-
64
- The many_to_one association is used when the table for the current class
65
- contains a foreign key that references the primary key in the table for the
66
- associated class. It is named 'many_to_one' because there can be many rows
67
- in the current table for each row in the associated table.
68
-
69
- # Database schema:
70
- # albums artists
71
- # :id /--> :id
72
- # :artist_id --/ :name
73
- # :name
74
-
75
- class Album
76
- # Uses singular form of associated model name
77
- many_to_one :artist
78
- end
79
-
80
- === one_to_many and one_to_one
81
-
82
- The one_to_many association is used when the table for the associated class
83
- contains a foreign key that references the primary key in the table for the
84
- current class. It is named 'one_to_many' because for each row in the
85
- current table there can be many rows in the associated table:
86
-
87
- The one_to_one association can be thought of as a subset of the one_to_many association,
88
- but where there can only be either 0 or 1 records in the associated table. This is
89
- useful if there is a unique constraint on the foreign key field in the associated table.
90
- It's also useful if you want to impose an order on the association and just want the
91
- first record returned.
92
-
93
- # Database schema:
94
- # artists albums
95
- # :id <----\ :id
96
- # :name \----- :artist_id
97
- # :name
98
-
99
- class Artist
100
- # Uses plural form of associated model name
101
- one_to_many :albums
102
-
103
- # Uses singular form of associated model name
104
- one_to_one :album
105
- end
106
-
107
- === many_to_many and one_through_one
108
-
109
- The many_to_many association allows each row in the current table to be associated
110
- to many rows in the associated table, and each row in the associated table to
111
- many rows in the current table, by using a join table to associate the two tables.
112
-
113
- The one_through_one association can be thought of as a subset of the many_to_many
114
- association, but where there can only be 0 or 1 records in the associated table.
115
- This is useful if there is a unique constraint on the foreign key in the join table
116
- that references the current table. It's also useful if you want to impose an order
117
- on the association and just want the first record returned. The one_through_one
118
- association is so named because it sets up a one-to-one association through a
119
- single join table.
120
-
121
- # Database schema:
122
- # albums
123
- # :id <----\
124
- # :name \ albums_artists
125
- # \---- :album_id
126
- # artists /---- :artist_id
127
- # :id <-----/
128
- # :name
129
-
130
- class Artist
131
- # Uses plural form of associated model name
132
- many_to_many :albums
133
-
134
- # Uses singular form of associated model name
135
- one_through_one :album
136
- end
137
-
138
- === Differences Between many_to_one and one_to_one
139
-
140
- If you want to setup a 1-1 relationship between two models, where the
141
- foreign key in one table references the associated table directly, you have to use
142
- many_to_one in one model, and one_to_one in the other model. How do you
143
- know which to use in which model?
144
-
145
- The simplest way to remember is that the model whose table has the foreign
146
- key uses many_to_one, and the other model uses one_to_one:
147
-
148
- # Database schema:
149
- # artists albums
150
- # :id <----\ :id
151
- # :name \----- :artist_id
152
- # :name
153
-
154
- class Artist
155
- one_to_one :album
156
- end
157
- class Album
158
- many_to_one :artist
159
- end
160
-
161
- == Most Common Options
162
-
163
- === :key
164
-
165
- The :key option must be used if the default column symbol that Sequel would use is not
166
- the correct column. For example:
167
-
168
- class Album
169
- # Assumes :key is :artist_id, based on association name of :artist
170
- many_to_one :artist
171
- end
172
- class Artist
173
- # Assumes :key is :artist_id, based on class name of Artist
174
- one_to_many :albums
175
- end
176
-
177
- However, if your schema looks like:
178
-
179
- # Database schema:
180
- # artists albums
181
- # :id <----\ :id
182
- # :name \----- :artistid # Note missing underscore
183
- # :name
184
-
185
- Then the default :key option will not be correct. To fix this, you need to
186
- specify an explicit :key option:
187
-
188
- class Album
189
- many_to_one :artist, key: :artistid
190
- end
191
- class Artist
192
- one_to_many :albums, key: :artistid
193
- end
194
-
195
- For many_to_many associations, the :left_key and :right_key options can be
196
- used to specify the column names in the join table, and the :join_table
197
- option can be used to specify the name of the join table:
198
-
199
- # Database schema:
200
- # albums
201
- # :id <----\
202
- # :name \ albumsartists
203
- # \---- :albumid
204
- # artists /---- :artistid
205
- # :id <-----/
206
- # :name
207
-
208
- class Artist
209
- # Note that :left_key refers to the foreign key pointing to the
210
- # current table, and :right_key the foreign key pointing to the
211
- # associated table.
212
- many_to_many :albums, left_key: :artistid, right_key: :albumid,
213
- join_table: :albumsartists
214
- end
215
- class Album
216
- many_to_many :artists, left_key: :albumid, right_key: :artistid,
217
- join_table: :albumsartists
218
- end
219
-
220
- === :class
221
-
222
- If the class of the association cannot be guessed directly by looking at
223
- the association name, you need to specify it via the :class option. For
224
- example, if you have two separate foreign keys in the albums table that
225
- both point to the artists table, maybe to indicate one artist is the
226
- vocalist and one is the composer, you'd have to use the :class option:
227
-
228
- # Database schema:
229
- # artists albums
230
- # :id <----\ :id
231
- # :name \----- :vocalist_id
232
- # \---- :composer_id
233
- # :name
234
-
235
- class Album
236
- many_to_one :vocalist, class: :Artist
237
- many_to_one :composer, class: :Artist
238
- end
239
- class Artist
240
- one_to_many :vocalist_albums, class: :Album, key: :vocalist_id
241
- one_to_many :composer_albums, class: :Album, key: :composer_id
242
- end
243
-
244
- == Self-referential Associations
245
-
246
- Self-referential associations are easy to handle in Sequel. The simplest
247
- example is a tree structure:
248
-
249
- # Database schema:
250
- # nodes
251
- # :id <--\
252
- # :parent_id ---/
253
- # :name
254
-
255
- class Node
256
- many_to_one :parent, class: self
257
- one_to_many :children, key: :parent_id, class: self
258
- end
259
-
260
- For many_to_many self_referential associations, it's fairly similar. Here's
261
- an example of a directed graph:
262
-
263
- # Database schema:
264
- # nodes edges
265
- # :id <----------- :successor_id
266
- # :name \----- :predecessor_id
267
-
268
- class Node
269
- many_to_many :direct_predecessors, left_key: :successor_id,
270
- right_key: :predecessor_id, join_table: :edges, class: self
271
- many_to_many :direct_successors, right_key: :successor_id,
272
- left_key: :predecessor_id, join_table: :edges, class: self
273
- end
274
-
275
- == Methods Added
276
-
277
- When you create an association, it's going to add instance methods to
278
- the class related to the association.
279
-
280
- All associations are going to have an instance method added with the
281
- same name as the association:
282
-
283
- @artist.albums
284
- @album.artists
285
-
286
- many_to_one and one_to_one associations will also have a setter method
287
- added to change the associated object:
288
-
289
- @album.artist = Artist.create(name: 'YJM')
290
-
291
- many_to_many and one_to_many associations will have three methods added:
292
-
293
- add_* :: to associate an object to the current object
294
- remove_* :: to disassociate an object from the current object
295
- remove_all_* :: to dissociate all currently associated objects
296
-
297
- Examples:
298
-
299
- @artist.add_album(@album)
300
- @artist.remove_album(@album)
301
- @artist.remove_all_albums
302
-
303
- Note that the remove_all_* method does not call remove hooks defined on
304
- the association, it just issues a single query to the database. If you
305
- want to remove all associated objects and call remove hooks, iterate
306
- over the array of associated objects and call remove_* for each:
307
-
308
- @artist.albums.each do |album|
309
- @artist.remove_album(album)
310
- end
311
-
312
- == Caching
313
-
314
- Associations are cached after being retrieved:
315
-
316
- @artist.album # Not cached - Database Query
317
- @artist.album # Cached - No Database Query
318
-
319
- @album.artists # Not cached - Database Query
320
- @album.artists # Cached - No Database Query
321
-
322
- You can choose to ignore the cached versions and do a database query to
323
- retrieve results by passing a <tt>reload: true</tt> option to the association method:
324
-
325
- @album.artists # Not cached - Database Query
326
- @album.artists # Cached - No Database Query
327
- @album.artists(reload: true) # Ignore cache - Database Query
328
-
329
- If you reload/refresh the object, it will automatically clear the
330
- associations cache for the object:
331
-
332
- @album.artists # Not cached - Database Query
333
- @album.artists # Cached - No Database Query
334
- @album.reload
335
- @album.artists # Not Cached - Database Query
336
-
337
- If you want direct access to the associations cache, use the associations
338
- instance method:
339
-
340
- @album.associations # {}
341
- @album.associations[:artists] # nil
342
- @album.artists # [<Artist ...>, ...]
343
- @album.associations[:artists] # [<Artist ...>, ...]
344
-
345
- === Code Reloading
346
-
347
- When declaring associations, Sequel caches association metadata in the association reflection. If you're doing any code reloading that doesn't involve restarting the related process, you should disable caching of the association reflection, to avoid stale model classes still being referenced after reloading:
348
-
349
- Sequel::Model.cache_associations = false
350
-
351
- == Dataset Method
352
-
353
- In addition to the above methods, associations also add an instance method
354
- ending in +_dataset+ that returns a dataset representing the objects in the associated table:
355
-
356
- @album.artist_id
357
- # 10
358
- @album.artist_dataset
359
- # SELECT * FROM artists WHERE (id = 10) LIMIT 1
360
-
361
- @artist.id
362
- # 20
363
- @artist.albums_dataset
364
- # SELECT * FROM albums WHERE (artist_id = 20)
365
-
366
- The association dataset is just like any other Sequel dataset, in that
367
- it can be further filtered, ordered, etc.:
368
-
369
- @artist.albums_dataset.
370
- where(Sequel.like(:name, 'A%')).
371
- order(:copies_sold).
372
- limit(10)
373
- # SELECT * FROM albums
374
- # WHERE ((artist_id = 20) AND (name LIKE 'A%' ESCAPE '\'))
375
- # ORDER BY copies_sold LIMIT 10
376
-
377
- Records retrieved using the +_dataset+ method are not cached in the
378
- associations cache.
379
-
380
- @album.artists_dataset.all # [<Artist ...>, ...]
381
- @album.associations[:artists] # nil
382
-
383
- == Dynamic Association Modification
384
-
385
- Similar to the +_dataset+ method, you can provide a block to the association
386
- method to customize the dataset that will be used to retrieve the records. So
387
- you can apply a filter in either of these two ways:
388
-
389
- @artist.albums_dataset.where(Sequel.like(:name, 'A%'))
390
- @artist.albums{|ds| ds.where(Sequel.like(:name, 'A%'))}
391
-
392
- While they both apply the same filter, using the +_dataset+ method does not
393
- apply any of the association callbacks or handle association reciprocals (see
394
- below for details about callbacks and reciprocals). Using a block instead handles
395
- all those things, and also caches its results in the associations cache (ignoring
396
- any previously cached value).
397
-
398
- == Filtering By Associations
399
-
400
- In addition to using the association method to get associated objects, you
401
- can also use associated objects in filters. For example, to get
402
- all albums for a given artist, you would usually do:
403
-
404
- @artist.albums
405
- # or @artist.albums_dataset for a dataset
406
-
407
- You can also do the following:
408
-
409
- Album.where(artist: @artist).all
410
- # or leave off the .all for a dataset
411
-
412
- For filtering by a single association, this isn't very useful. However, unlike
413
- using the association method, using a filter allows you to filter by multiple
414
- associations:
415
-
416
- Album.where(artist: @artist, publisher: @publisher)
417
-
418
- This will return all albums by that artist and published by that publisher.
419
- This isn't possible using just the association method approach, though you
420
- can combine the approaches:
421
-
422
- @artist.albums_dataset.where(publisher: @publisher)
423
-
424
- This doesn't just work for +many_to_one+ associations, it also works for
425
- the other associations:
426
-
427
- Album.one_to_one :album_info
428
- # The album related to that AlbumInfo instance
429
- Album.where(album_info: AlbumInfo[2])
430
-
431
- Album.one_to_many :tracks
432
- # The album related to that Track instance
433
- Album.where(tracks: Track[3])
434
-
435
- Album.many_to_many :tags
436
- # All albums related to that Tag instance
437
- Album.where(tags: Tag[4])
438
-
439
- Album.one_through_one :tag
440
- # All albums related to that Tag instance
441
- Album.where(tag: Tag[4])
442
-
443
- Note that for +one_to_many+ and +many_to_many+ associations, you still
444
- use the plural form even though only a single model object is given.
445
-
446
- You can also exclude by associations:
447
-
448
- Album.exclude(artist: @artist).all
449
-
450
- This will return all albums not by that artist.
451
-
452
- You can also provide an array with multiple model objects:
453
-
454
- Album.where(artist: [@artist1, @artist2]).all
455
-
456
- Similar to using an array of integers or strings, this will return
457
- all albums whose artist is one of those two artists. You can also
458
- use +exclude+ if you want all albums not by either of those artists:
459
-
460
- Album.exclude(artist: [@artist1, @artist2]).all
461
-
462
- If you are using a +one_to_many+ or +many_to_many+ association, you
463
- may want to return records where the records matches all of multiple
464
- records, instead of matching any of them. For example:
465
-
466
- Album.where(tags: [@tag1, @tag2])
467
-
468
- This matches albums that are associated with either @tag1 or @tag2 or
469
- both. If you only want ones that you are associated with both, you can
470
- use separate filter calls:
471
-
472
- Album.where(tags: @tag1).where(tags: @tag2)
473
-
474
- Or the array form of condition specifiers:
475
-
476
- Album.where([[:tags, @tag1], [:tags, @tag2]])
477
-
478
- These will return albums associated with both @tag1 and @tag2.
479
-
480
- You can also provide a dataset value when filtering by associations:
481
-
482
- Album.where(artist: Artist.where(Sequel.like(:name, 'A%'))).all
483
-
484
- This will return all albums whose artist starts with 'A'. Like
485
- the other forms, this can be inverted:
486
-
487
- Album.exclude(artist: Artist.where(Sequel.like(:name, 'A%'))).all
488
-
489
- This will return all albums whose artist does not start with 'A'.
490
-
491
- Filtering by associations even works for associations that have
492
- conditions added via the :conditions option or a block:
493
-
494
- Album.one_to_many :popular_tags, clone: :tags do |ds|
495
- ds.where{times_used > 1000}
496
- end
497
- Album.where(popular_tags: [@tag1, @tag2])
498
-
499
- This will return all albums that whose popular tags would include
500
- at least one of those tags.
501
-
502
- Note that filtering by associations does not work for associations
503
- that use blocks with instance-specific code.
504
-
505
- == Name Collisions
506
-
507
- Because associations create instance methods, it's possible to override
508
- existing instance methods if you name an association the same as an
509
- existing method. For example, <tt>values</tt> and <tt>associations</tt>
510
- would be bad association names.
511
-
512
- == Database Schema
513
-
514
- Creating an association doesn't modify the database schema. Sequel
515
- assumes your associations reflect the existing database schema. If not,
516
- you should modify your schema before creating the associations.
517
-
518
- === many_to_one/one_to_many
519
-
520
- For example, for the following model code:
521
-
522
- class Album
523
- many_to_one :artist
524
- end
525
- class Artist
526
- one_to_many :albums
527
- end
528
-
529
- You probably want the following database schema:
530
-
531
- # albums artists
532
- # :id /--> :id
533
- # :artist_id --/ :name
534
- # :name
535
-
536
- Which could be created using the following Sequel code:
537
-
538
- DB.create_table(:artists) do
539
- # Primary key must be set explicitly
540
- primary_key :id
541
- String :name, null: false, unique: true
542
- end
543
- DB.create_table(:albums) do
544
- primary_key :id
545
- # Table that foreign key references needs to be set explicitly
546
- # for a database foreign key reference to be created.
547
- foreign_key :artist_id, :artists, null: false
548
- String :name, null: false, unique: true
549
- end
550
-
551
- If you already had a schema such as:
552
-
553
- # Database schema:
554
- # albums artists
555
- # :id :id
556
- # :name :name
557
-
558
- Then you just need to add the column:
559
-
560
- DB.alter_table(:albums) do
561
- add_foreign_key :artist_id, :artists, null: false
562
- end
563
-
564
- === many_to_many
565
-
566
- With many_to_many associations, the default join table for the association
567
- uses the sorted underscored names of both model classes. For example, with
568
- the following model code:
569
-
570
- class Album
571
- many_to_many :artists
572
- end
573
- class Artist
574
- many_to_many :albums
575
- end
576
-
577
- The default join table name would be <tt>albums_artists</tt>, not
578
- <tt>artists_albums</tt>, because:
579
-
580
- ["artists", "albums"].sort.join('_')
581
- # "albums_artists"
582
-
583
- Assume you already had the albums and artists tables created, and you just
584
- wanted to add an albums_artists join table to create the following schema:
585
-
586
- # Database schema:
587
- # albums
588
- # :id <----\
589
- # :name \ albums_artists
590
- # \---- :album_id
591
- # artists /---- :artist_id
592
- # :id <-----/
593
- # :name
594
-
595
- You could use the following Sequel code:
596
-
597
- DB.create_join_table(album_id: :albums, artist_id: :artists)
598
- # or
599
- DB.create_table(:albums_artists) do
600
- foreign_key :album_id, :albums, null: false
601
- foreign_key :artist_id, :artists, null: false
602
- primary_key [:album_id, :artist_id]
603
- index [:artist_id, :album_id]
604
- end
605
-
606
- == Association Scope
607
-
608
- If you nest your Sequel::Model classes inside modules, then you should know
609
- that Sequel will only look in the same module for associations by default.
610
- So the following code will work fine:
611
-
612
- module App
613
- class Artist < Sequel::Model
614
- one_to_many :albums
615
- end
616
- class Album < Sequel::Model
617
- many_to_one :artist
618
- end
619
- end
620
-
621
- However, if you enclose your model classes inside two different modules,
622
- things will not work by default:
623
-
624
- module App1
625
- class Artist < Sequel::Model
626
- one_to_many :albums
627
- end
628
- end
629
- module App2
630
- class Album < Sequel::Model
631
- many_to_one :artist
632
- end
633
- end
634
-
635
- To fix this, you need to specify the full model class name using the
636
- :class option:
637
-
638
- module App1
639
- class Artist < Sequel::Model
640
- one_to_many :albums, class: "App2::Album"
641
- end
642
- end
643
- module App2
644
- class Album < Sequel::Model
645
- many_to_one :artist, class: "App1::Artist"
646
- end
647
- end
648
-
649
- If both classes are in the same module, but the default class name
650
- used is not correct, you need to specify the full class name with the
651
- :class option:
652
-
653
- module App1
654
- class AlbumArtist < Sequel::Model
655
- one_to_many :albums
656
- end
657
- class Album < Sequel::Model
658
- many_to_one :artist, class: "App1::AlbumArtist"
659
- end
660
- end
661
-
662
- == Method Details
663
-
664
- In all of these methods, _association_ is replaced by the symbol you
665
- pass to the association.
666
-
667
- === _association_(opts={}) (e.g. albums)
668
-
669
- For +many_to_one+ and +one_to_one+ associations, the _association_ method
670
- returns either the single object associated, or nil if no object is
671
- associated.
672
-
673
- @artist = @album.artist
674
-
675
- For +one_to_many+ and +many_to_many+ associations, the _association_ method
676
- returns an array of associated objects, which may be empty if no objects
677
- are currently associated.
678
-
679
- @albums = @artist.albums
680
-
681
- === _association_=(object_to_associate) (e.g. artist=) [+many_to_one+ and +one_to_one+]
682
-
683
- The _association_= method sets up an association of the passed object to
684
- the current object. For +many_to_one+ associations, this sets the
685
- foreign key for the current object to point to the associated
686
- object's primary key.
687
-
688
- @album.artist = @artist
689
-
690
- For +one_to_one+ associations, this sets the foreign key of the
691
- associated object to the primary key value of the current object.
692
-
693
- For +many_to_one+ associations, this does not save the current object.
694
- For +one_to_one+ associations, this does save the associated object.
695
-
696
- === add_<i>association</i>(object_to_associate) (e.g. add_album) [+one_to_many+ and +many_to_many+]
697
-
698
- The add_<i>association</i> method associates the passed object to the current
699
- object. For +one_to_many+ associations, it sets the foreign key of the
700
- associated object to the primary key value of the current object, and
701
- saves the associated object. For +many_to_many+ associations, this inserts
702
- a row into the join table with the foreign keys set to the primary key values
703
- of the current and associated objects. Note that the singular form of the
704
- association name is used in this method.
705
-
706
- @artist.add_album(@album)
707
-
708
- In addition to passing an actual associated object, you can pass a hash,
709
- and a new associated object will be created from them:
710
-
711
- @artist.add_album(name: 'RF') # creates Album object
712
-
713
- The add_<i>association</i> method returns the new associated object:
714
-
715
- @album = @artist.add_album(name: 'RF')
716
-
717
- Note that the add_* methods for +one_to_many+ persist the changes by
718
- saving the passed in (or newly created) object. However, to avoid
719
- silent failures of these methods, they explicitly raise exceptions
720
- even when raise_on_save_failure is false for the associated model.
721
- You can disable this behavior (i.e. return nil instead of raising
722
- exceptions on a save failure) by setting the <tt>raise_on_save_failure: false</tt>
723
- option for the association.
724
-
725
- === remove_<i>association</i>(object_to_disassociate) (e.g. remove_album) [+one_to_many+ and +many_to_many+]
726
-
727
- The remove_<i>association</i> method disassociates the passed object from
728
- the current object. For +one_to_many+ associations, it sets the foreign key of
729
- the associated object to NULL, and saves the associated object. For
730
- +many_to_many+ associations, this deletes the matching row in the join table.
731
- Similar to the add_<i>association</i> method, the singular form of the
732
- association name is used in this method.
733
-
734
- @artist.remove_album(@album)
735
-
736
- Note that this does not delete <tt>@album</tt> from the database, it only
737
- disassociates it from the <tt>@artist</tt>. To delete <tt>@album</tt> from the
738
- database:
739
-
740
- @album.destroy
741
-
742
- The add_<i>association</i> and remove_<i>association</i> methods should be
743
- thought of as adding and removing from the association, not from the database.
744
-
745
- In addition to passing the object directly to remove_<i>association</i>, you
746
- can also pass the associated object's primary key:
747
-
748
- @artist.remove_album(10)
749
-
750
- This will look up the associated object using the key, and remove that
751
- album.
752
-
753
- The remove_<i>association</i> method returns the now disassociated object:
754
-
755
- @album = @artist.remove_album(10)
756
-
757
- === remove_all_<i>association</i> (e.g. remove_all_albums) [+one_to_many+ and +many_to_many+]
758
-
759
- The remove_all_<i>association</i> method disassociates all currently associated
760
- objects. For +one_to_many+ associations, it sets the foreign key of
761
- all associated objects to NULL in a single query. For +many_to_many+
762
- associations, this deletes all matching rows in the join table.
763
- Unlike the add_<i>association</i> and remove_<i>association</i> method, the
764
- plural form of the association name is used in this method.
765
- The remove_all_<i>association</i> method returns the previously cached associated
766
- records, or nil if there were no cached associated records.
767
-
768
- === <i>association</i>_dataset (e.g. albums_dataset)
769
-
770
- The <i>association</i>_dataset method returns a dataset that represents
771
- all associated objects. This dataset is like any other Sequel dataset,
772
- in that it can be filtered, ordered, etc.:
773
-
774
- ds = @artist.albums_dataset.where(Sequel.like(:name, 'A%')).order(:copies_sold)
775
-
776
- Unlike most other Sequel datasets, association datasets have a couple of
777
- added methods:
778
-
779
- ds.model_object # @artist
780
- ds.association_reflection # same as Artist.association_reflection(:albums)
781
-
782
- For a more info on Sequel's reflection capabilities see the {Reflection page}[rdoc-ref:doc/reflection.rdoc].
783
-
784
- == Overriding Method Behavior
785
-
786
- Sequel is designed to be very flexible. If the default behavior of the
787
- association modification methods isn't what you desire, you can override
788
- the methods in your classes. However, you should be aware that for each
789
- of the association modification methods described, there is a private
790
- method that is preceded by an underscore that does the actual
791
- modification. The public method without the underscore handles caching
792
- and callbacks, and shouldn't be overridden by the user.
793
-
794
- In addition to overriding the private method in your class, you can also
795
- use association options to change which method Sequel defines. The
796
- only difference between the two is that if you use an association option
797
- to change the method Sequel defines, you cannot call super to get the
798
- default behavior.
799
-
800
- === :setter (_<i>association</i>= method)
801
-
802
- Let's say you want to set a specific field whenever associating an object
803
- using the association setter method. For example, let's say you have
804
- a file_under column for each album to tell you where to file it. If the
805
- album is associated with an artist, it should be filed under the artist's
806
- name and the album's name, otherwise it should just use the album's name.
807
-
808
- class Album < Sequel::Model
809
- many_to_one :artist, setter: (lambda do |artist|
810
- if artist
811
- self.artist_id = artist.id
812
- self.file_under = "#{artist.name}-#{name}"
813
- else
814
- self.artist_id = nil
815
- self.file_under = name
816
- end
817
- end)
818
- end
819
-
820
- The above example is contrived, as you would generally use a before_save model
821
- hook to handle such a modification. However, if you only modify the album's
822
- artist using the artist= method, this approach may perform better.
823
-
824
- === :adder (\_add_<i>association</i> method)
825
-
826
- Continuing with the same example, here's how you would handle the same case if
827
- you also wanted to handle the Artist#add_album method:
828
-
829
- class Artist < Sequel::Model
830
- one_to_many :albums, adder: (lambda do |album|
831
- album.update(artist_id: id, file_under: "#{name}-#{album.name}")
832
- end)
833
- end
834
-
835
- You can set this to +nil+ to not create a add_<i>association</i> method.
836
-
837
- === :remover (\_remove_<i>association</i> method)
838
-
839
- Continuing with the same example, here's how you would handle the same case if
840
- you also wanted to handle the Artist#remove_album method:
841
-
842
- class Artist < Sequel::Model
843
- one_to_many :albums, remover: (lambda do |album|
844
- album.update(artist_id: nil, file_under: album.name)
845
- end)
846
- end
847
-
848
- You can set this to +nil+ to not create a remove_<i>association</i> method.
849
-
850
- === :clearer (\_remove_all_<i>association</i> method)
851
-
852
- Continuing with the same example, here's how you would handle the same case if
853
- you also wanted to handle the Artist#remove_all_albums method:
854
-
855
- class Artist < Sequel::Model
856
- one_to_many :albums, clearer: (lambda do
857
- # This is Dataset#update, not Model#update, so the file_under: :name
858
- # ends up being "SET file_under = name" in SQL.
859
- albums_dataset.update(artist_id: nil, file_under: :name)
860
- end)
861
- end
862
-
863
- You can set this to +nil+ to not create a remove_all_<i>association</i> method.
864
-
865
- === :no_dataset_method
866
-
867
- Setting this to true will result in the <i>association</i>_dataset method
868
- not being defined. This can save memory if you only use the <i>association</i>
869
- method and do not call the <i>association</i>_dataset method directly or
870
- indirectly.
871
-
872
- === :no_association_method
873
-
874
- Setting this to true will result in the <i>association</i> method
875
- not being defined. This can save memory if you only use the
876
- <i>association</i>_dataset method and do not call the <i>association</i> method
877
- directly or indirectly.
878
-
879
- == Association Options
880
-
881
- Sequel's associations mostly share the same options. For ease of understanding,
882
- they are grouped here by section.
883
-
884
- The defaults for any of these options can be set at the class level using
885
- <tt>Sequel::Model.default_association_options</tt>. To make
886
- associations read only by default:
887
-
888
- Sequel::Model.default_association_options[:read_only] = true
889
-
890
- Many of these options are specific to particular association types, and
891
- the defaults can be set on a per association type basis. To make one_to_many
892
- associations read only by default:
893
-
894
- Sequel::Model.default_association_type_options[:one_to_many] = {read_only: true}
895
-
896
- === Association Dataset Modification Options
897
-
898
- ==== block
899
-
900
- All association defining methods take a block that is passed the
901
- default dataset and should return a modified copy of the dataset to
902
- use for the association. For example, if you wanted an association
903
- that returns all albums of an artist that went gold (sold at least
904
- 500,000 copies):
905
-
906
- Artist.one_to_many :gold_albums, class: :Album do |ds|
907
- ds.where{copies_sold > 500000}
908
- end
909
-
910
- The result of the block is cached as an optimization. One of the side
911
- effects of that is that if your block depends on external state, it won't
912
- work correctly unless you setup a delayed evaluation. For example:
913
-
914
- Artist.one_to_many :gold_albums, class: :Album do |ds|
915
- ds.where{copies_sold > $gold_limit}
916
- end
917
-
918
- In this case if you change <tt>$gold_limit</tt> later, the changes won't
919
- effect the association. If you want to pick up changes to <tt>$gold_limit</tt>,
920
- you need to setup a delayed evaluation:
921
-
922
- Artist.one_to_many :gold_albums, class: :Album do |ds|
923
- ds.where{copies_sold > Sequel.delay{$gold_limit}}
924
- end
925
-
926
- ==== :class
927
-
928
- This is the class of the associated objects that will be used. It's
929
- one of the most commonly used options. If it is not given, it guesses
930
- based on the name of the association, including considering the namespace
931
- of the current model. If a *_to_many association is used, this uses the
932
- singular form of the association name. For example:
933
-
934
- Album.many_to_one :artist # guesses Artist
935
- Artist.one_to_many :albums # guesses Album
936
- Foo::Artist.one_to_many :albums # guesses Foo::Album
937
-
938
- However, for more complex associations, especially ones that add
939
- additional filters beyond the foreign/primary key relationships, the
940
- default class guessed will be wrong:
941
-
942
- # guesses GoldAlbum
943
- Artist.one_to_many :gold_albums do |ds|
944
- ds.where{copies_sold > 500000}
945
- end
946
-
947
- You can specify the :class option using the class itself, a Symbol,
948
- or a String:
949
-
950
- Album.many_to_one :artist, class: Artist # Class
951
- Album.many_to_one :artist, class: :Artist # Symbol
952
- Album.many_to_one :artist, class: "Artist" # String
953
-
954
- If you are namespacing your models, and you need to specify the :class
955
- option, the path you give to the :class option should be the full path
956
- to the associated class including any namespaces:
957
-
958
- Foo::Album.many_to_one :artist # Uses Foo::Artist
959
- Foo::Album.many_to_one :artist, class: "Artist" # Uses Artist
960
- Foo::Album.many_to_one :artist, class: "Foo::Artist" # Uses Foo::Artist
961
-
962
- ==== :key
963
-
964
- For +many_to_one+ associations, this is the foreign_key in the current model's
965
- table that references the associated model's primary key as a symbol.
966
- Defaults to :<i>association</i>_id.
967
-
968
- Album.many_to_one :artist, key: :artistid
969
-
970
- For +one_to_one+ and +one_to_many+ associations, is the foreign key in
971
- associated model's table that references current model's primary key, as a
972
- symbol. Defaults to :"#{self.name.underscore}_id".
973
-
974
- Artist.one_to_many :albums, key: :artistid
975
-
976
- In both cases an array of symbols can be used for a composite key association:
977
-
978
- Apartment.many_to_one :building, key: [:city, :address]
979
-
980
- ==== :conditions
981
-
982
- The conditions to use to filter the association, can be any argument passed to +where+.
983
- If you use a hash or an array of two element arrays, this will also be used as a
984
- filter when using eager_graph or association_join to load the association.
985
-
986
- If you do not use a hash or array of two element arrays, you should use the
987
- :graph_conditions, :graph_only_conditions, or :graph_block option or you will not
988
- be able to use eager_graph or association_join with the association.
989
-
990
- Artist.one_to_many :good_albums, class: :Album, conditions: {good: true}
991
- @artist.good_albums
992
- # SELECT * FROM albums WHERE ((artist_id = 1) AND (good IS TRUE))
993
-
994
- ==== :order
995
-
996
- The column(s) by which to order the association dataset. Can be a
997
- singular column or an array.
998
-
999
- Artist.one_to_many :albums_by_name, class: :Album, order: :name
1000
- Artist.one_to_many :albums_by_num_tracks, class: :Album, order: [:num_tracks, :name]
1001
-
1002
- ==== :select
1003
-
1004
- The columns to SELECT when loading the association. For most associations,
1005
- it defaults to nil, so * is used. For +many_to_many+ associations, it
1006
- defaults to the associated class's table_name.*, which means it doesn't include
1007
- the columns from the join table. This is to prevent the common issue where the
1008
- join table includes columns with the same name as columns in the associated
1009
- table, in which case the joined table's columns would usually end up clobbering
1010
- the values in the associated table. If you want to include the join table
1011
- attributes, you can use this option, but beware that the join table columns
1012
- can clash with columns from the associated table, so you should alias any
1013
- columns that have the same name in both the join table and the associated
1014
- table. Example:
1015
-
1016
- Artist.one_to_many :albums, select: [:id, :name]
1017
- Album.many_to_many :tags, select: [Sequel[:tags].*, Sequel[:albums_tags][:number]]
1018
-
1019
- ==== :limit
1020
-
1021
- Limit the number of records to the provided value:
1022
-
1023
- Artist.one_to_many :best_selling_albums, class: :Album, order: :copies_sold, limit: 5
1024
-
1025
- Use an array with two arguments for the value to specify a limit and an offset.
1026
-
1027
- Artist.one_to_many :next_best_selling_albums, class: :Album, order: :copies_sold, limit: [10, 5]
1028
- # LIMIT 10 OFFSET 5
1029
-
1030
- This probably doesn't make a lot of sense for *_to_one associations, though you
1031
- could use it to specify an offset.
1032
-
1033
- ==== :join_table [+many_to_many+, +one_through_one+]
1034
-
1035
- Name of table that includes the foreign keys to both the current model and the
1036
- associated model, as a symbol. Defaults to the name of current model and name
1037
- of associated model, pluralized, underscored, sorted, and joined with '_'.
1038
- Here's an example of the defaults:
1039
-
1040
- Artist.many_to_many :albums, join_table: :albums_artists
1041
- Album.many_to_many :artists, join_table: :albums_artists
1042
- Person.many_to_many :colleges, join_table: :colleges_people
1043
-
1044
- ==== :left_key [+many_to_many+, +one_through_one+]
1045
-
1046
- Foreign key in join table that points to current model's primary key, as a
1047
- symbol. Defaults to :"#{model_name.underscore}_id".
1048
-
1049
- Album.many_to_many :tags, left_key: :album_id
1050
-
1051
- Can use an array of symbols for a composite key association.
1052
-
1053
- ==== :right_key [+many_to_many+, +one_through_one+]
1054
-
1055
- Foreign key in join table that points to associated model's primary key, as a
1056
- symbol. Defaults to :"#{association_name.singularize}_id" for +many_to_many+
1057
- and :"#{association_name}_id" for +one_through_one+.
1058
-
1059
- Album.many_to_many :tags, right_key: :tag_id
1060
-
1061
- Can use an array of symbols for a composite key association.
1062
-
1063
- ==== :distinct
1064
-
1065
- Use the DISTINCT clause when selecting associating object, both when lazy
1066
- loading and eager loading via eager (but not when using eager_graph).
1067
-
1068
- This is most useful for many_to_many associations that use join tables that
1069
- contain more than just the foreign keys, where you are storing additional
1070
- information. For example, if you have a database of people, degree types, and
1071
- colleges, and you want to return all people from a given college, you may want
1072
- to use :distinct so that if a person has two separate degrees from the same
1073
- college, they won't show up twice.
1074
-
1075
- ==== :clone
1076
-
1077
- The :clone option clones an existing association, taking the options
1078
- you specified for that association, and making a copy of them for this
1079
- association. Other options provided by this association are then merged
1080
- into the cloned options.
1081
-
1082
- This is commonly used if you have a bunch of similar associations that
1083
- you want to DRY up:
1084
-
1085
- one_to_many :english_verses, class: :LyricVerse, key: :lyricsongid,
1086
- order: :number, conditions: {languageid: 1}
1087
- one_to_many :romaji_verses, clone: :english_verses, conditions: {languageid: 2}
1088
- one_to_many :japanese_verses, clone: :english_verses, conditions: {languageid: 3}
1089
-
1090
- Note that for the final two asociations, you didn't have to specify the :class,
1091
- :key, or :order options, as they were copied by the :clone option. By specifying
1092
- the :conditions option for the final two associations, it overrides the :conditions
1093
- option of the first association, it doesn't attempt to merge them.
1094
-
1095
- In addition to the options hash, the :clone option will copy a block argument
1096
- from the existing situation. If you want a cloned association to not have the
1097
- same block as the association you are cloning from, specify the block: nil option
1098
- in addition to the :clone option.
1099
-
1100
- ==== :dataset
1101
-
1102
- This is generally only specified for custom associations that aren't based on
1103
- primary/foreign key relationships. It should be a proc that is instance_execed
1104
- to get the base dataset to use before the other options are applied.
1105
-
1106
- If the proc accepts an argument, it is passed the related association reflection.
1107
- For best performance, it's recommended that custom associations call the
1108
- +associated_dataset+ method on the association reflection as the starting point
1109
- for the dataset to return. The +associated_dataset+ method will return a
1110
- dataset based on the associated class with most of the association options
1111
- already applied, and the proc should return a modified copy of this dataset.
1112
-
1113
- Here's an example of an association of songs to artists through lyrics, where
1114
- the artist can perform any one of four tasks for the lyric:
1115
-
1116
- Artist.one_to_many :songs, dataset: (lambda do |r|
1117
- r.associated_dataset.select_all(:songs).
1118
- join(:lyrics, id: :lyricid, id=>[:composer_id, :arranger_id, :vocalist_id, :lyricist_id])
1119
- end)
1120
- Artist.first.songs_dataset
1121
- # SELECT songs.* FROM songs
1122
- # INNER JOIN lyrics ON ((lyrics.id = songs.lyric_id)
1123
- # AND (1 IN (composer_id, arranger_id, vocalist_id, lyricist_id))
1124
-
1125
- ==== :extend
1126
-
1127
- A module or array of modules to extend the dataset with. These are used to
1128
- set up association extensions. For more information , please see the
1129
- {Advanced Associations page}[rdoc-ref:doc/advanced_associations.rdoc].
1130
-
1131
- ==== :primary_key [+many_to_one+, +one_to_one+, +one_to_many+]
1132
-
1133
- The column that the :key option references, as a symbol. For +many_to_one+
1134
- associations, this column is in the associated table. For +one_to_one+ and
1135
- +one_to_many+ associations, this column is in the current table. In both cases,
1136
- it defaults to the primary key of the table. Can use an
1137
- array of symbols for a composite key association.
1138
-
1139
- Artist.set_primary_key :arid
1140
- Artist.one_to_many :albums, primary_key: :arid
1141
- Album.one_to_many :artist, primary_key: :arid
1142
-
1143
- ==== :left_primary_key [+many_to_many+, +one_through_one+]
1144
-
1145
- Column in current table that :left_key option points to, as a symbol.
1146
- Defaults to primary key of current table.
1147
-
1148
- Album.set_primary_key :alid
1149
- Album.many_to_many :tags, left_primary_key: :alid
1150
-
1151
- Can use an array of symbols for a composite key association.
1152
-
1153
- ==== :right_primary_key [+many_to_many+, +one_through_one+]
1154
-
1155
- Column in associated table that :right_key points to, as a symbol.
1156
- Defaults to primary key of the associated table.
1157
-
1158
- Tag.set_primary_key :tid
1159
- Album.many_to_many :tags, right_primary_key: :tid
1160
-
1161
- Can use an array of symbols for a composite key association.
1162
-
1163
- ==== :join_table_block [+many_to_many+, +one_through_one+]
1164
-
1165
- A proc that can be used to modify the dataset used in the add/remove/remove_all
1166
- methods. It's separate from the association block, as that is called on a
1167
- join of the join table and the associated table, whereas this option just
1168
- applies to the join table. It can be used to make sure that filters are used
1169
- when deleting.
1170
-
1171
- Artist.many_to_many :lead_guitar_albums, class: :Album, join_table_block: (lambda do |ds|
1172
- ds.where(instrument_id: 5)
1173
- end)
1174
-
1175
- ==== :join_table_db [+many_to_many+, +one_through_one+]
1176
-
1177
- A Sequel::Database to use for the join table. Specifying this option switches the
1178
- loading to use a separate query for the join table. This is useful if the
1179
- join table is not located in the same database as the associated table, or
1180
- if the database account with access to the associated table doesn't have
1181
- access to the join table.
1182
-
1183
- For example, if the Album class uses a different Sequel::Database than the Artist
1184
- class, and the join table is in the database that the Artist class uses:
1185
-
1186
- Artist.many_to_many :lead_guitar_albums, class: :Album, join_table_db: Artist.db
1187
-
1188
- This option also affects the add/remove/remove_all methods, by changing
1189
- which database is used for inserts/deletes from the join table (add/remove/remove_all
1190
- defaults to use the current model's database instead of the associated model's database).
1191
-
1192
- === Callback Options
1193
-
1194
- All callbacks can be specified as a Symbol, Proc, or array of both/either
1195
- specifying a callback to call. Symbols are interpreted as instance methods
1196
- that are called with the associated object. Procs are called with the receiver
1197
- as the first argument and the associated object as the second argument. If
1198
- an array is given, all of them are called in order.
1199
-
1200
- Before callbacks are often used to check preconditions, they can call Model#cancel_action
1201
- to signal Sequel to abort the modification. If any before callback
1202
- calls cancel_action, the remaining before callbacks are not called and the modification
1203
- is aborted.
1204
-
1205
- ==== :before_add [+one_to_many+, +many_to_many+]
1206
-
1207
- Called before adding an object to the association:
1208
-
1209
- class Artist
1210
- # Don't allow adding an album to an artist if it has no tracks
1211
- one_to_many :albums, before_add: lambda{|ar, al| ar.cancel_action if al.num_tracks == 0}
1212
- end
1213
-
1214
- ==== :after_add [+one_to_many+, +many_to_many+]
1215
-
1216
- Called after adding an object to the association:
1217
-
1218
- class Artist
1219
- # Log all associations of albums to an audit logging table
1220
- one_to_many :albums, after_add: :log_add_album
1221
-
1222
- private
1223
-
1224
- def log_add_album(album)
1225
- DB[:audit_logs].insert(log: "Album #{album.inspect} associated to #{inspect}")
1226
- end
1227
- end
1228
-
1229
- ==== :before_remove [+one_to_many+, +many_to_many+]
1230
-
1231
- Called before removing an object from the association using <tt>remove_<i>association</i></tt>:
1232
-
1233
- class Artist
1234
- # Don't allow removing a self-titled album
1235
- one_to_many :albums, before_remove: lambda{|ar, al| ar.cancel_action if al.name == ar.name}
1236
- end
1237
-
1238
- This is not called when using <tt>remove_all_<i>association</i></tt>.
1239
-
1240
- ==== :after_remove [+one_to_many+, +many_to_many+]
1241
-
1242
- Called after removing an object from the association using <tt>remove_<i>association</i></tt>:
1243
-
1244
- class Artist
1245
- # Log all disassociations of albums to an audit logging table
1246
- one_to_many :albums, after_remove: :log_remove_album
1247
-
1248
- private
1249
-
1250
- def log_remove_album(album)
1251
- DB[:audit_logs].insert(log: "Album #{album.inspect} disassociated from #{inspect}")
1252
- end
1253
- end
1254
-
1255
- This is not called when using <tt>remove_all_<i>association</i></tt>.
1256
-
1257
- ==== :before_set [+many_to_one+, +one_to_one+]
1258
-
1259
- Called before the _<i>association</i>= method is called to modify the objects:
1260
-
1261
- class Album
1262
- # Don't associate the album with an artist if the year the album was
1263
- # released is less than the year the artist/band started.
1264
- many_to_one :artist, before_set: lambda{|al, ar| al.cancel_action if al.year < ar.year_started}
1265
- end
1266
-
1267
- ==== :after_set [+many_to_one+, +one_to_one+]
1268
-
1269
- Called after the _<i>association</i>= method is called to modify the objects:
1270
-
1271
- class Album
1272
- # Log all disassociations of albums to an audit logging table
1273
- many_to_one :artist, after_set: :log_artist_set
1274
-
1275
- private
1276
-
1277
- def log_artist_set(artist)
1278
- DB[:audit_logs].insert(log: "Artist for album #{inspect} set to #{artist.inspect}")
1279
- end
1280
- end
1281
-
1282
- ==== :after_load
1283
-
1284
- Called after retrieving the associated records from the database.
1285
-
1286
- class Artist
1287
- # Cache all album names to a single string when retrieving the albums.
1288
- one_to_many :albums, after_load: :cache_album_names
1289
-
1290
- attr_reader :album_names
1291
-
1292
- private
1293
-
1294
- def cache_album_names(albums)
1295
- @album_names = albums.map(&:name).join(", ")
1296
- end
1297
- end
1298
-
1299
- Generally used if you know you will always want a certain action done
1300
- when retrieving the association.
1301
-
1302
- For +one_to_many+ and +many_to_many+ associations, both the argument to
1303
- symbol callbacks and the second argument to proc callbacks will be an
1304
- array of associated objects instead of a single object.
1305
-
1306
- ==== :uniq [+many_to_many+]
1307
-
1308
- Adds a after_load callback that makes the array of objects unique. In many
1309
- cases, using the :distinct option is a better approach.
1310
-
1311
- === Eager Loading via eager (query per association) Options
1312
-
1313
- ==== :eager
1314
-
1315
- The associations to eagerly load via eager when loading the associated object(s).
1316
- This is useful for example if you always want to eagerly load dependent
1317
- associations when loading this association.
1318
-
1319
- For example, if you know that any time that you want to load an artist's
1320
- albums, you are also going to want access to the album's tracks as well:
1321
-
1322
- # Eager load tracks when loading the albums
1323
- Artist.one_to_many :albums, eager: :tracks
1324
-
1325
- You can also use a hash or array to specify multiple dependent associations
1326
- to eagerly load:
1327
-
1328
- # Eager load the albums' tracks and the tracks' tags when loading the albums
1329
- Artist.one_to_many :albums, eager: {tracks: :tags}
1330
- # Eager load the albums' tags and tracks when loading the albums
1331
- Artist.one_to_many :albums, eager: [:tags, :tracks]
1332
- # Eager load the albums' tags, tracks, and tracks' tags when loading the albums
1333
- Artist.one_to_many :albums, eager: [:tags, {tracks: :tags}]
1334
-
1335
- ==== :eager_loader
1336
-
1337
- A custom loader to use when eagerly load associated objects via eager.
1338
- For many details and examples of custom eager loaders, please see the
1339
- {Advanced Associations guide}[rdoc-ref:doc/advanced_associations.rdoc].
1340
-
1341
- ==== :eager_loader_key
1342
-
1343
- A symbol for the key column to use to populate the key hash for the eager
1344
- loader. Generally does not need to be set manually, defaults to the key
1345
- method used. Can be set to nil to not populate the key hash (better for
1346
- performance if a custom eager loader does not use the key_hash).
1347
-
1348
- ==== :eager_block
1349
-
1350
- If given, should be a proc to use instead of the association method block
1351
- when eagerly loading. To not use a block when eager loading when one is
1352
- used normally, set to nil. It's very uncommon to need this option.
1353
-
1354
- === Eager Loading via eager_graph (one query with joins) Options
1355
-
1356
- ==== :eager_graph
1357
-
1358
- The associations to eagerly load via eager_graph when loading the associated
1359
- object(s). This is useful for example if you always want to eagerly load dependent
1360
- associations when loading this association, but you want to filter or order the
1361
- association based on dependent associations:
1362
-
1363
- Artist.one_to_many :albums_with_short_tracks, class: :Album, eager_graph: :tracks do |ds|
1364
- ds.where{tracks[:seconds] < 120}
1365
- end
1366
- Artist.one_to_many :albums_by_track_name, class: :Album, eager_graph: :tracks do |ds|
1367
- ds.order{tracks[:name]}
1368
- end
1369
-
1370
- You can also use a hash or array of arguments for :eager_graph, similar to
1371
- what the :eager option accepts.
1372
-
1373
- ==== :graph_conditions
1374
-
1375
- The additional conditions to use on the SQL join when eagerly loading the
1376
- association via eager_graph. Should be a hash or an array of two element
1377
- arrays. If not specified, the :conditions option is used if it is a hash or
1378
- array of two element arrays.
1379
-
1380
- Artist.one_to_many :active_albums, class: :Album, graph_conditions: {active: true}
1381
-
1382
- Note that these conditions on the association are in addition to the default
1383
- conditions specified by the foreign/primary keys. If you want to replace
1384
- the conditions specified by the foreign/primary keys, you need the
1385
- :graph_only_conditions options.
1386
-
1387
- ==== :graph_block
1388
-
1389
- The block to pass to Dataset#join_table when eagerly loading the association
1390
- via eager_graph. This is useful to specify conditions that can't be specified
1391
- in a hash or array of two element arrays.
1392
-
1393
- Artist.one_to_many :gold_albums, class: :Album,
1394
- graph_block: proc{|j,lj,js| Sequel[j][:copies_sold] > 500000}
1395
-
1396
- ==== :graph_join_type
1397
-
1398
- The type of SQL join to use when eagerly loading the association via
1399
- eager_graph. Defaults to :left_outer. This is useful if you want to
1400
- ensure that only artists that have albums are returned:
1401
-
1402
- Artist.one_to_many :albums, graph_join_type: :inner
1403
- # Will exclude artists without an album
1404
- Artist.eager_graph(:albums).all
1405
-
1406
- ==== :graph_select
1407
-
1408
- A column or array of columns to select from the associated table
1409
- when eagerly loading the association via eager_graph. Defaults to all
1410
- columns in the associated table.
1411
-
1412
- ==== :graph_only_conditions
1413
-
1414
- The conditions to use on the SQL join when eagerly loading the association via
1415
- eager_graph, instead of the default conditions specified by the
1416
- foreign/primary keys. This option causes the :graph_conditions option to be
1417
- ignored. This can be useful if the keys you are using are strings and you
1418
- want to do a case insensitive comparison. For example, let's say that instead
1419
- of integer keys, you used string keys based on the album or artist name, and
1420
- that the album was associated to the artist by name. However, you weren't
1421
- enforcing case sensitivity between the keys, so you still want to return albums
1422
- where the artist's name differs in case:
1423
-
1424
- Artist.one_to_many :albums, key: :artist_name,
1425
- graph_only_conditions: nil,
1426
- graph_block: (proc do |j,lj,js|
1427
- {Sequel.function(:lower, Sequel[j][:artist_name])=> Sequel.function(:lower, Sequel[lj][:name])}
1428
- end)
1429
-
1430
- Note how :graph_only_conditions is set to nil to ignore any existing conditions,
1431
- and :graph_block is used to set up the case insensitive comparison.
1432
-
1433
- Another case where :graph_only_conditions may be used is if you want to use
1434
- a JOIN USING or NATURAL JOIN for the graph:
1435
-
1436
- # JOIN USING
1437
- Artist.one_to_many :albums, key: :artist_name, graph_only_conditions: [:artist_name]
1438
-
1439
- # NATURAL JOIN
1440
- Artist.one_to_many :albums, key: :artist_name, graph_only_conditions: nil, graph_join_type: :natural
1441
-
1442
- ==== :graph_alias_base
1443
-
1444
- The base name to use for the table alias when eager graphing. Defaults to the name
1445
- of the association. If the alias name has already been used in the query, Sequel will create
1446
- a unique alias by appending a numeric suffix (e.g. alias_0, alias_1, ...) until the alias is
1447
- unique.
1448
-
1449
- This is mostly useful if you have associations with the same name in many models, and you want
1450
- to be able to easily tell which table alias corresponds to which association when eagerly
1451
- graphing multiple associations with the same name.
1452
-
1453
- You can override this option on a per-eager_graph basis by specifying the association as an
1454
- SQL::AliasedExpression instead of a symbol:
1455
-
1456
- Album.eager_graph(Sequel.as(:artist, :a))
1457
-
1458
- ==== :eager_grapher
1459
-
1460
- Sets up a custom grapher to use when eager loading the objects via eager_graph.
1461
- This is the eager_graph analogue to the :eager_loader option. This isn't generally
1462
- needed, as one of the other eager_graph related association options is usually sufficient.
1463
-
1464
- If specified, should be a proc that accepts a single hash argument, which will contain
1465
- at least the following keys:
1466
-
1467
- :callback :: A callback proc used to dynamically modify the dataset to graph into the
1468
- current dataset, before such graphing is done. This is nil if no callback
1469
- proc is used.
1470
- :implicit_qualifier :: The alias that was used for the current table (since you can cascade associations).
1471
- :join_type :: Override the join type to use when graphing.
1472
- :limit_strategy :: The limit strategy symbol to use when graphing (for limited associations only)
1473
- :self :: The dataset that is doing the eager loading
1474
- :table_alias :: An alias to use for the table to graph for this association.
1475
-
1476
- Example:
1477
-
1478
- Artist.one_to_many :self_title_albums, class: :Album,
1479
- eager_grapher: (lambda do |eo|
1480
- eo[:self].graph(:albums, {artist_id: :id, name: :name},
1481
- table_alias: eo[:table_alias], implicit_qualifier: eo[:implicit_qualifier])
1482
- end)
1483
-
1484
- ==== :order_eager_graph
1485
-
1486
- Whether to add the order to the dataset's order when graphing via eager_graph.
1487
- Defaults to true, so set to false to disable.
1488
-
1489
- Sequel has to do some guess work when attempting to add the association's
1490
- order to an eager_graphed dataset. In most cases it does so correctly, but
1491
- if it has problems, you'll probably want to set this option to false.
1492
-
1493
- ==== :graph_order
1494
-
1495
- Override the order added when using eager_graph, instead of using the one
1496
- defined in :order. This is useful if :order contains qualified identifiers,
1497
- as the qualifiers may not match the aliases automatically used by eager_graph.
1498
- This should contain unqualified identifiers, and eager_graph will automatically
1499
- qualify them with the appropriate alias.
1500
-
1501
- ==== :graph_use_association_block
1502
-
1503
- Setting this to true makes eager_graph apply the association block to the
1504
- associated dataset before graphing the associated dataset into the receiver.
1505
- In most cases when this option is used and the association has a block, the
1506
- dataset returned by eager_graph will contain a JOIN to a subquery.
1507
-
1508
- By default (when this option is not used), the association block will be ignored
1509
- when using eager_graph:
1510
-
1511
- Artist.one_to_many :tracks do |ds|
1512
- ds.where(foo: 3)
1513
- end
1514
- Artist.eager_graph(:tracks)
1515
- # SELECT albums.id, tracks.id AS tracks_id, tracks.album_id
1516
- # FROM albums
1517
- # LEFT OUTER JOIN tracks
1518
- # ON (tracks.album_id = albums.id)
1519
-
1520
- When this option is used, the block will be respected:
1521
-
1522
- Artist.one_to_many :tracks, graph_use_association_block: true do |ds|
1523
- ds.where(foo: 3)
1524
- end
1525
- Artist.eager_graph(:tracks)
1526
- # SELECT albums.id, tracks.id AS tracks_id, tracks.album_id
1527
- # FROM albums
1528
- # LEFT OUTER JOIN (SELECT * FROM tracks WHERE (foo = 3)) AS tracks
1529
- # ON (tracks.album_id = albums.id)
1530
-
1531
- ==== :graph_join_table_conditions [+many_to_many+, +one_through_one+]
1532
-
1533
- The additional conditions to use on the SQL join for the join table when
1534
- eagerly loading the association via eager_graph. Should be a hash or an array
1535
- of two element arrays.
1536
-
1537
- Let's say you have a database of people, colleges, and a table called
1538
- degrees_received that includes a string field specifying the name of the
1539
- degree, and you want to eager load all colleges for people where the person
1540
- has received a specific degree:
1541
-
1542
- Person.many_to_many :bs_degree_colleges, class: :College,
1543
- join_table: :degrees_received,
1544
- graph_join_table_conditions: {degree: 'BS'}
1545
-
1546
- ==== :graph_join_table_block [+many_to_many+, +one_through_one+]
1547
-
1548
- The block to pass to join_table for the join table when eagerly loading the
1549
- association via eager_graph. This is used for similar reasons as :graph_block,
1550
- but is only used for +many_to_many+ associations when graphing the join
1551
- table into the dataset. It's used in the same place as
1552
- :graph_join_table_conditions but like :graph_block, is needed for situations
1553
- where the conditions can't be specified as a hash or array of two element
1554
- arrays.
1555
-
1556
- Let's say you have a database of people, colleges, and a table called
1557
- degrees_received that includes a string field specifying the name of the
1558
- degree, and you want to eager load all colleges for people where the person
1559
- has received a bachelor's degree (degree starting with B):
1560
-
1561
- Person.many_to_many :bachelor_degree_colleges, class: :College,
1562
- join_table: :degrees_received,
1563
- graph_join_table_block: proc{|j,lj,js| Sequel[j][:degree].like('B%')}
1564
-
1565
- This should be done when graphing the join table, instead of when graphing the
1566
- final table, as :degree is a column of the join table.
1567
-
1568
- ==== :graph_join_table_join_type [+many_to_many+, +one_through_one+]
1569
-
1570
- The type of SQL join to use for the join table when eagerly loading the
1571
- association via eager_graph. Defaults to the :graph_join_type option or
1572
- :left_outer. This exists mainly for consistency in the unlikely case that
1573
- you want to use a different join type when JOINing to the join table then
1574
- you want to use for JOINing to the final table
1575
-
1576
- ==== :graph_join_table_only_conditions [+many_to_many+, +one_through_one+]
1577
-
1578
- The conditions to use on the SQL join for the join table when eagerly loading
1579
- the association via eager_graph, instead of the default conditions specified
1580
- by the foreign/primary keys. This option causes the
1581
- :graph_join_table_conditions option to be ignored. This is only useful if
1582
- you want to replace the default foreign/primary key conditions that Sequel
1583
- would use when eagerly graphing.
1584
-
1585
- === Associations Based on SQL Expressions Options
1586
-
1587
- Sequel's associations can work not just with columns, but also with
1588
- arbitrary SQL expressions. For example, on PostgreSQL, you can store
1589
- foreign keys to other tables in hstore, json, or jsonb columns, and Sequel
1590
- can work with such constructs, including full support for
1591
- eager loading.
1592
-
1593
- There's actually two parts to supporting associations based on SQL
1594
- expressions. First is you must have an instance method in the model
1595
- that returns the value that the SQL expression would return. Second
1596
- is you must have an SQL expression object. If Sequel has access to
1597
- a model instance and needs to get the value of the expression, it
1598
- calls the method to get the value. If Sequel does not have access
1599
- to a model instance, but needs to use the SQL expression in a query,
1600
- it will use the SQL expression object.
1601
-
1602
- Below is an example storing foreign keys to other tables in a
1603
- PostgreSQL hstore column, using the +pg_json+ and +pg_json_ops+
1604
- extensions.
1605
-
1606
- # Example schema:
1607
- # albums artists
1608
- # :id /---> :id
1609
- # :meta ---/ :name
1610
- # :name
1611
- class Album < Sequel::Model
1612
- many_to_one :artist, key_column: Sequel.pg_jsonb(:meta)['artist_id'].cast(String).cast(Integer)
1613
-
1614
- def artist_id
1615
- meta['artist_id'].to_i
1616
- end
1617
- end
1618
- class Artist < Sequel::Model
1619
- one_to_many :albums, key: Sequel.pg_jsonb(:meta)['artist_id'].cast(String).cast(Integer), key_method: :artist_id
1620
- end
1621
-
1622
- # Example schema:
1623
- # albums albums_artists artists
1624
- # :id <----- :meta -------> :id
1625
- # :name :name
1626
- class Album < Sequel::Model
1627
- many_to_many :artists, left_key: Sequel.pg_jsonb(:meta)['album_id'].cast(String).cast(Integer),
1628
- right_key: Sequel.pg_jsonb(:meta)['artist_id'].cast(String).cast(Integer)
1629
- end
1630
- class Artist < Sequel::Model
1631
- many_to_many :albums, left_key: Sequel.pg_jsonb(:meta)['artist_id'].cast(String).cast(Integer),
1632
- right_key: Sequel.pg_jsonb(:meta)['album_id'].cast(String).cast(Integer)
1633
- end
1634
-
1635
- ==== :key_column [+many_to_one+]
1636
-
1637
- Like the :key option, but :key references the method name, while
1638
- :key_column references the underlying column/expression.
1639
-
1640
- ==== :primary_key_method [+many_to_one+]
1641
-
1642
- Like the :primary_key option, but :primary_key references the column/expression
1643
- name, while :primary_key_method references the method name.
1644
-
1645
- ==== :primary_key_column [+one_to_many+, +one_to_one+]
1646
-
1647
- Like the :primary_key option, but :primary_key references the method name, while
1648
- :primary_key_column references the underlying column/expression.
1649
-
1650
- ==== :key_method [+one_to_many+, +one_to_one+]
1651
-
1652
- Like the :key option, but :key references the column/expression
1653
- name, while :key_method references the method name.
1654
-
1655
- ==== :left_primary_key_column [+many_to_many+, +one_through_one+]
1656
-
1657
- Like the :left_primary_key option, but :left_primary_key references the method name, while
1658
- :left_primary_key_column references the underlying column/expression.
1659
-
1660
- ==== :right_primary_key_method [+many_to_many+, +one_through_one+]
1661
-
1662
- Like the :right_primary_key option, but :right_primary_key references the column/expression
1663
- name, while :right_primary_key_method references the method name.
1664
-
1665
- === Advanced Options
1666
-
1667
- ==== :reciprocal
1668
-
1669
- The symbol name of the reciprocal association, if it exists. By default,
1670
- Sequel will try to determine it by looking at the associated model's
1671
- associations for a association that matches the current association's key(s).
1672
- Set to nil to not use a reciprocal.
1673
-
1674
- Reciprocals are used in Sequel to modify the matching cached associations
1675
- in associated objects when calling association methods on the current object.
1676
- For example, when you retrieve objects in a one_to_many association, Sequel will
1677
- automatically set the matching many_to_one association in the associated
1678
- objects. The result of this is that code that does this:
1679
-
1680
- @artist.albums.each{|album| album.artist.name}
1681
-
1682
- only does one database query, because when the @artist's albums are retrieved,
1683
- the cached artist association for each album is set to @artist.
1684
-
1685
- In addition to the one_to_many retrieval case, the association modification
1686
- methods affect the reciprocals as well:
1687
-
1688
- # Sets the cached artist association for @album to @artist
1689
- @artist.add_album(@album)
1690
-
1691
- # Sets the cached artist association for @album to nil
1692
- @artist.remove_album(@album)
1693
-
1694
- # Sets the cached artist association to nil for the @artist's
1695
- # cached albums association
1696
- @artist.remove_all_albums
1697
-
1698
- # Remove @album from the artist1's cached albums association, and add @album
1699
- # to @artist2's cached albums association.
1700
- @album.artist # @artist1
1701
- @album.artist = @artist2
1702
-
1703
- Sequel can usually guess the correct reciprocal, but if you have multiple
1704
- associations to the same associated class that use the same keys, you may
1705
- want to specify the :reciprocal option manually to ensure the correct
1706
- one is used.
1707
-
1708
- ==== :read_only
1709
-
1710
- For +many_to_one+ and +one_to_one+ associations, do not add a setter method.
1711
- For +one_to_many+ and +many_to_many+, do not add the add_<i>association</i>,
1712
- remove_<i>association</i>, or remove_all_<i>association</i> methods.
1713
-
1714
- If you are not using the association modification methods, setting this
1715
- value to true will save memory.
1716
-
1717
- ==== :validate
1718
-
1719
- Set to false to not validate when implicitly saving any associated object.
1720
- When using the +one_to_many+ association modification methods, the +one_to_one+
1721
- setter method, or creating a new object by passing a hash to the
1722
- add_<i>association</i> method, Sequel will automatically save the object.
1723
- If you don't want to validate objects when these implicit saves are done,
1724
- the validate option should be set to false.
1725
-
1726
- ==== :raise_on_save_failure [+one_to_many+ associations]
1727
-
1728
- Set to false to not raise an exception when validation or a before hook
1729
- fails when implicitly saving an associated object in the add_* or remove_*
1730
- methods. This mirrors the raise_on_save_failure model setting, which these
1731
- methods do not respect (by design).
1732
-
1733
- If you use this option, you must explicitly check all add_* and remove_* return
1734
- values to see if they were successful.
1735
-
1736
- ==== :allow_eager
1737
-
1738
- If set to false, you cannot load the association eagerly via eager or
1739
- eager_graph.
1740
-
1741
- Artist.one_to_many :albums, allow_eager: false
1742
- Artist.eager(:albums) # Raises Sequel::Error
1743
- Artist.eager_graph(:albums) # Raises Sequel::Error
1744
-
1745
- This is usually used if the association dataset depends on specific values in
1746
- model instance that would not be valid when eager loading for multiple
1747
- instances.
1748
-
1749
- ==== :allow_eager_graph
1750
-
1751
- If set to false, you cannot load the association eagerly via eager_graph.
1752
-
1753
- Artist.one_to_many :albums, allow_eager_graph: false
1754
- Artist.eager(:albums) # Allowed
1755
- Artist.eager_graph(:albums) # Raises Sequel::Error
1756
-
1757
- This is useful if you still want to allow loading via eager, but do not want
1758
- to allow loading via eager graph, possibly because the association does not
1759
- support joins.
1760
-
1761
- ==== :allow_filtering_by
1762
-
1763
- If set to false, you cannot use the association when filtering.
1764
-
1765
- Artist.one_to_many :albums, allow_filtering_by: false
1766
- Artist.where(albums: Album.where(name: 'A')).all # Raises Sequel::Error
1767
-
1768
- This is useful if such filtering cannot work, such as when a subquery cannot
1769
- be used because the necessary tables are not in the same database.
1770
-
1771
- ==== :instance_specific
1772
-
1773
- This allows you to override the setting of whether the dataset contains instance
1774
- specific code. If you are passing a block to the association,
1775
- Sequel sets this to true by default, which disables some optimizations that
1776
- would be invalid if the association is instance specific. If you know that the
1777
- block does not contain instance specific code, you can set this to false to
1778
- reenable the optimizations. Instance specific code is mostly commonly calling
1779
- model instance methods inside an association block, but also
1780
- includes cases where the association block can return different values based
1781
- on the runtime environment, such as calls to <tt>Time.now</tt> in the block.
1782
- Associations that use the :dataset option are always considered instance specific,
1783
- even if explicitly specified otherwise.
1784
-
1785
- ==== :cartesian_product_number
1786
-
1787
- The number of joins completed by this association that could cause more
1788
- than one row for each row in the current table (default: 0 for *_one
1789
- associations, 1 for *_to_many associations).
1790
-
1791
- This should only be modified in specific cases. For example, if you have
1792
- a one_to_one association that can actually return more than one row
1793
- (where the default association method will just return the first), or
1794
- a many_to_many association where there is a unique index in the join table
1795
- so that you know only one object will ever be associated through the
1796
- association.
1797
-
1798
- ==== :class_namespace
1799
-
1800
- If the :class option is specified as a symbol or string, the default namespace
1801
- in which to look up the class. If the :class option is not specified as a
1802
- symbol or string, this option is ignored. This namespace can be overridden
1803
- by starting the string or symbol with <tt>::</tt>:
1804
-
1805
- Foo::Album.many_to_one :artist, class: "Artist" # Uses Artist
1806
- Foo::Album.many_to_one :artist, class: "Artist", class_namespace: 'Foo' # Uses Foo::Artist
1807
- Foo::Album.many_to_one :artist, class: "Foo::Artist", class_namespace: 'Foo' # Uses Foo::Foo::Artist
1808
- Foo::Album.many_to_one :artist, class: "::Artist", class_namespace: 'Foo' # Uses Artist
1809
- Foo::Album.many_to_one :artist, class: "::Foo::Artist", class_namespace: 'Foo' # Uses Foo::Artist
1810
-
1811
- ==== :methods_module
1812
-
1813
- The module that the methods created by the association will be placed
1814
- into. Defaults to the module containing the model's columns. Any module
1815
- given to this option is not included in the model's class automatically,
1816
- so you are responsible for doing that manually.
1817
-
1818
- This is only useful in rare cases, such as when a plugin that adds
1819
- associations depends on another plugin that defines instance methods of
1820
- the same name. In that case, the instance methods of the dependent
1821
- plugin would override the association methods created by the main
1822
- plugin.
1823
-
1824
- ==== :eager_limit_strategy
1825
-
1826
- This setting determines what strategy to use for eager loading the associations
1827
- that use the :limit setting to limit the number of returned records. You
1828
- can't use LIMIT directly, since you want a limit for each group of
1829
- associated records, not a LIMIT on the total number of records returned
1830
- by the dataset.
1831
-
1832
- In general, Sequel picks an appropriate strategy, so it is not usually
1833
- necessary to specify a strategy. You can specify true for this option to
1834
- have Sequel choose which strategy to use (this is the default). You can
1835
- specify a symbol to manually choose a strategy. The available strategies are:
1836
-
1837
- :union :: Uses one or more UNION queries with a subquery for each record
1838
- you are eagerly loading for (this is the default strategy).
1839
- :distinct_on :: Uses DISTINCT ON to ensure only the first matching record
1840
- is loaded (only used for one_*_one associations without
1841
- offsets on PostgreSQL).
1842
- :window_function :: Uses a ROW_NUMBER window functions to ensure the
1843
- correctly limited/offset records are returned.
1844
- :ruby :: Uses ruby array slicing to emulate database limiting/offsetting.
1845
-
1846
- ==== :subqueries_per_union
1847
-
1848
- The number of subqueries per union query to use when eager loading for a
1849
- limited association using a union strategy. This defaults to 40, but the
1850
- optimum number depends on the database in use and the latency between the
1851
- database and the application.
1852
-
1853
- ==== :filter_limit_strategy
1854
-
1855
- The strategy to use when filtering by limited associations. In general
1856
- Sequel will choose either a :distinct_on, :window_function, or
1857
- :correlated_subquery strategy based on the association type and what
1858
- the database supports, but you can override that if necessary using
1859
- this option.