activerecord 3.2.22.4 → 4.0.13
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2799 -617
- data/MIT-LICENSE +1 -1
- data/README.rdoc +23 -32
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +40 -34
- data/lib/active_record/association_relation.rb +22 -0
- data/lib/active_record/associations/alias_tracker.rb +4 -2
- data/lib/active_record/associations/association.rb +60 -46
- data/lib/active_record/associations/association_scope.rb +46 -40
- data/lib/active_record/associations/belongs_to_association.rb +17 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +81 -28
- data/lib/active_record/associations/builder/belongs_to.rb +73 -56
- data/lib/active_record/associations/builder/collection_association.rb +54 -40
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +23 -41
- data/lib/active_record/associations/builder/has_many.rb +8 -64
- data/lib/active_record/associations/builder/has_one.rb +13 -50
- data/lib/active_record/associations/builder/singular_association.rb +13 -13
- data/lib/active_record/associations/collection_association.rb +130 -96
- data/lib/active_record/associations/collection_proxy.rb +916 -63
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +15 -13
- data/lib/active_record/associations/has_many_association.rb +35 -8
- data/lib/active_record/associations/has_many_through_association.rb +37 -17
- data/lib/active_record/associations/has_one_association.rb +42 -19
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +39 -22
- data/lib/active_record/associations/join_dependency/join_base.rb +2 -2
- data/lib/active_record/associations/join_dependency/join_part.rb +21 -8
- data/lib/active_record/associations/join_dependency.rb +30 -9
- data/lib/active_record/associations/join_helper.rb +1 -11
- data/lib/active_record/associations/preloader/association.rb +29 -33
- data/lib/active_record/associations/preloader/collection_association.rb +1 -1
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +2 -2
- data/lib/active_record/associations/preloader/has_many_through.rb +6 -2
- data/lib/active_record/associations/preloader/has_one.rb +1 -1
- data/lib/active_record/associations/preloader/through_association.rb +13 -17
- data/lib/active_record/associations/preloader.rb +20 -43
- data/lib/active_record/associations/singular_association.rb +11 -11
- data/lib/active_record/associations/through_association.rb +3 -3
- data/lib/active_record/associations.rb +223 -282
- data/lib/active_record/attribute_assignment.rb +134 -154
- data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
- data/lib/active_record/attribute_methods/dirty.rb +36 -29
- data/lib/active_record/attribute_methods/primary_key.rb +45 -31
- data/lib/active_record/attribute_methods/query.rb +5 -4
- data/lib/active_record/attribute_methods/read.rb +67 -90
- data/lib/active_record/attribute_methods/serialization.rb +133 -70
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +51 -45
- data/lib/active_record/attribute_methods/write.rb +34 -39
- data/lib/active_record/attribute_methods.rb +268 -108
- data/lib/active_record/autosave_association.rb +80 -73
- data/lib/active_record/base.rb +54 -451
- data/lib/active_record/callbacks.rb +60 -22
- data/lib/active_record/coders/yaml_column.rb +18 -21
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +347 -197
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +146 -138
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +25 -19
- data/lib/active_record/connection_adapters/abstract/quoting.rb +19 -3
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +151 -142
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +499 -217
- data/lib/active_record/connection_adapters/abstract/transaction.rb +208 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +209 -44
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +169 -61
- data/lib/active_record/connection_adapters/column.rb +67 -36
- data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +28 -29
- data/lib/active_record/connection_adapters/mysql_adapter.rb +200 -73
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +98 -0
- data/lib/active_record/connection_adapters/postgresql/cast.rb +160 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +240 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +374 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +183 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +508 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +544 -899
- data/lib/active_record/connection_adapters/schema_cache.rb +76 -16
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +595 -16
- data/lib/active_record/connection_handling.rb +98 -0
- data/lib/active_record/core.rb +472 -0
- data/lib/active_record/counter_cache.rb +107 -108
- data/lib/active_record/dynamic_matchers.rb +115 -63
- data/lib/active_record/errors.rb +36 -18
- data/lib/active_record/explain.rb +15 -63
- data/lib/active_record/explain_registry.rb +30 -0
- data/lib/active_record/explain_subscriber.rb +8 -4
- data/lib/active_record/fixture_set/file.rb +55 -0
- data/lib/active_record/fixtures.rb +159 -155
- data/lib/active_record/inheritance.rb +93 -59
- data/lib/active_record/integration.rb +8 -8
- data/lib/active_record/locale/en.yml +8 -1
- data/lib/active_record/locking/optimistic.rb +39 -43
- data/lib/active_record/locking/pessimistic.rb +4 -4
- data/lib/active_record/log_subscriber.rb +19 -9
- data/lib/active_record/migration/command_recorder.rb +102 -33
- data/lib/active_record/migration/join_table.rb +15 -0
- data/lib/active_record/migration.rb +411 -173
- data/lib/active_record/model_schema.rb +81 -94
- data/lib/active_record/nested_attributes.rb +173 -131
- data/lib/active_record/null_relation.rb +67 -0
- data/lib/active_record/persistence.rb +254 -106
- data/lib/active_record/query_cache.rb +18 -36
- data/lib/active_record/querying.rb +19 -15
- data/lib/active_record/railtie.rb +113 -38
- data/lib/active_record/railties/console_sandbox.rb +3 -4
- data/lib/active_record/railties/controller_runtime.rb +4 -3
- data/lib/active_record/railties/databases.rake +115 -368
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +7 -3
- data/lib/active_record/reflection.rb +110 -61
- data/lib/active_record/relation/batches.rb +29 -29
- data/lib/active_record/relation/calculations.rb +155 -125
- data/lib/active_record/relation/delegation.rb +94 -18
- data/lib/active_record/relation/finder_methods.rb +151 -203
- data/lib/active_record/relation/merger.rb +188 -0
- data/lib/active_record/relation/predicate_builder.rb +85 -42
- data/lib/active_record/relation/query_methods.rb +793 -146
- data/lib/active_record/relation/spawn_methods.rb +43 -150
- data/lib/active_record/relation.rb +293 -173
- data/lib/active_record/result.rb +48 -7
- data/lib/active_record/runtime_registry.rb +17 -0
- data/lib/active_record/sanitization.rb +41 -54
- data/lib/active_record/schema.rb +19 -12
- data/lib/active_record/schema_dumper.rb +41 -41
- data/lib/active_record/schema_migration.rb +46 -0
- data/lib/active_record/scoping/default.rb +56 -52
- data/lib/active_record/scoping/named.rb +78 -103
- data/lib/active_record/scoping.rb +54 -124
- data/lib/active_record/serialization.rb +6 -2
- data/lib/active_record/serializers/xml_serializer.rb +9 -15
- data/lib/active_record/statement_cache.rb +26 -0
- data/lib/active_record/store.rb +131 -15
- data/lib/active_record/tasks/database_tasks.rb +204 -0
- data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +144 -0
- data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
- data/lib/active_record/test_case.rb +67 -38
- data/lib/active_record/timestamp.rb +16 -11
- data/lib/active_record/transactions.rb +73 -51
- data/lib/active_record/validations/associated.rb +19 -13
- data/lib/active_record/validations/presence.rb +65 -0
- data/lib/active_record/validations/uniqueness.rb +110 -57
- data/lib/active_record/validations.rb +18 -17
- data/lib/active_record/version.rb +7 -6
- data/lib/active_record.rb +63 -45
- data/lib/rails/generators/active_record/migration/migration_generator.rb +45 -8
- data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +4 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
- data/lib/rails/generators/active_record/model/model_generator.rb +5 -4
- data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
- data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
- data/lib/rails/generators/active_record.rb +3 -5
- metadata +43 -29
- data/examples/associations.png +0 -0
- data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
- data/lib/active_record/dynamic_finder_match.rb +0 -68
- data/lib/active_record/dynamic_scope_match.rb +0 -23
- data/lib/active_record/fixtures/file.rb +0 -65
- data/lib/active_record/identity_map.rb +0 -162
- data/lib/active_record/observer.rb +0 -121
- data/lib/active_record/session_store.rb +0 -360
- data/lib/rails/generators/active_record/migration.rb +0 -15
- data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
- data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
- data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,12 +1,15 @@
|
|
1
|
-
require 'active_support/core_ext/array/wrap'
|
2
1
|
require 'active_support/core_ext/enumerable'
|
3
|
-
require 'active_support/core_ext/module/delegation'
|
4
|
-
require 'active_support/core_ext/object/blank'
|
5
2
|
require 'active_support/core_ext/string/conversions'
|
6
3
|
require 'active_support/core_ext/module/remove_method'
|
7
|
-
require '
|
4
|
+
require 'active_record/errors'
|
8
5
|
|
9
6
|
module ActiveRecord
|
7
|
+
class AssociationNotFoundError < ConfigurationError #:nodoc:
|
8
|
+
def initialize(record, association_name)
|
9
|
+
super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
10
13
|
class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
|
11
14
|
def initialize(reflection, associated_class = nil)
|
12
15
|
super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
|
@@ -21,7 +24,7 @@ module ActiveRecord
|
|
21
24
|
|
22
25
|
class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError #:nodoc:
|
23
26
|
def initialize(owner_class_name, reflection, source_reflection)
|
24
|
-
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}'.")
|
27
|
+
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}' without 'source_type'. Try adding 'source_type: \"#{reflection.name.to_s.classify}\"' to 'has_many :through' definition.")
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
@@ -156,7 +159,7 @@ module ActiveRecord
|
|
156
159
|
association = association_instance_get(name)
|
157
160
|
|
158
161
|
if association.nil?
|
159
|
-
reflection
|
162
|
+
raise AssociationNotFoundError.new(self, name) unless reflection = self.class.reflect_on_association(name)
|
160
163
|
association = reflection.association_class.new(self, reflection)
|
161
164
|
association_instance_set(name, association)
|
162
165
|
end
|
@@ -194,30 +197,10 @@ module ActiveRecord
|
|
194
197
|
# * <tt>Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?</tt>
|
195
198
|
# * <tt>Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,</tt>
|
196
199
|
# * <tt>Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone),</tt>
|
197
|
-
# <tt>Project#milestones.delete(milestone), Project#milestones.
|
200
|
+
# <tt>Project#milestones.delete(milestone), Project#milestones.destroy(milestone), Project#milestones.find(milestone_id),</tt>
|
198
201
|
# <tt>Project#milestones.build, Project#milestones.create</tt>
|
199
202
|
# * <tt>Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1),</tt>
|
200
|
-
# <tt>Project#categories.delete(category1)</tt>
|
201
|
-
#
|
202
|
-
# === Overriding generated methods
|
203
|
-
#
|
204
|
-
# Association methods are generated in a module that is included into the model class,
|
205
|
-
# which allows you to easily override with your own methods and call the original
|
206
|
-
# generated method with +super+. For example:
|
207
|
-
#
|
208
|
-
# class Car < ActiveRecord::Base
|
209
|
-
# belongs_to :owner
|
210
|
-
# belongs_to :old_owner
|
211
|
-
# def owner=(new_owner)
|
212
|
-
# self.old_owner = self.owner
|
213
|
-
# super
|
214
|
-
# end
|
215
|
-
# end
|
216
|
-
#
|
217
|
-
# If your model class is <tt>Project</tt>, the module is
|
218
|
-
# named <tt>Project::GeneratedFeatureMethods</tt>. The GeneratedFeatureMethods module is
|
219
|
-
# included in the model class immediately after the (anonymous) generated attributes methods
|
220
|
-
# module, meaning an association will override the methods for an attribute with the same name.
|
203
|
+
# <tt>Project#categories.delete(category1), Project#categories.destroy(category1)</tt>
|
221
204
|
#
|
222
205
|
# === A word of warning
|
223
206
|
#
|
@@ -255,17 +238,39 @@ module ActiveRecord
|
|
255
238
|
# others.size | X | X | X
|
256
239
|
# others.length | X | X | X
|
257
240
|
# others.count | X | X | X
|
258
|
-
# others.sum(args
|
241
|
+
# others.sum(*args) | X | X | X
|
259
242
|
# others.empty? | X | X | X
|
260
243
|
# others.clear | X | X | X
|
261
244
|
# others.delete(other,other,...) | X | X | X
|
262
245
|
# others.delete_all | X | X | X
|
246
|
+
# others.destroy(other,other,...) | X | X | X
|
263
247
|
# others.destroy_all | X | X | X
|
264
248
|
# others.find(*args) | X | X | X
|
265
249
|
# others.exists? | X | X | X
|
250
|
+
# others.distinct | X | X | X
|
266
251
|
# others.uniq | X | X | X
|
267
252
|
# others.reset | X | X | X
|
268
253
|
#
|
254
|
+
# === Overriding generated methods
|
255
|
+
#
|
256
|
+
# Association methods are generated in a module that is included into the model class,
|
257
|
+
# which allows you to easily override with your own methods and call the original
|
258
|
+
# generated method with +super+. For example:
|
259
|
+
#
|
260
|
+
# class Car < ActiveRecord::Base
|
261
|
+
# belongs_to :owner
|
262
|
+
# belongs_to :old_owner
|
263
|
+
# def owner=(new_owner)
|
264
|
+
# self.old_owner = self.owner
|
265
|
+
# super
|
266
|
+
# end
|
267
|
+
# end
|
268
|
+
#
|
269
|
+
# If your model class is <tt>Project</tt>, the module is
|
270
|
+
# named <tt>Project::GeneratedFeatureMethods</tt>. The GeneratedFeatureMethods module is
|
271
|
+
# included in the model class immediately after the (anonymous) generated attributes methods
|
272
|
+
# module, meaning an association will override the methods for an attribute with the same name.
|
273
|
+
#
|
269
274
|
# == Cardinality and associations
|
270
275
|
#
|
271
276
|
# Active Record associations can be used to describe one-to-one, one-to-many and many-to-many
|
@@ -308,11 +313,11 @@ module ActiveRecord
|
|
308
313
|
# end
|
309
314
|
# class Programmer < ActiveRecord::Base
|
310
315
|
# has_many :assignments
|
311
|
-
# has_many :projects, :
|
316
|
+
# has_many :projects, through: :assignments
|
312
317
|
# end
|
313
318
|
# class Project < ActiveRecord::Base
|
314
319
|
# has_many :assignments
|
315
|
-
# has_many :programmers, :
|
320
|
+
# has_many :programmers, through: :assignments
|
316
321
|
# end
|
317
322
|
#
|
318
323
|
# For the second way, use +has_and_belongs_to_many+ in both models. This requires a join table
|
@@ -401,14 +406,35 @@ module ActiveRecord
|
|
401
406
|
# * All unsaved (<tt>new_record? == true</tt>) members of the collection are automatically
|
402
407
|
# saved when the parent is saved.
|
403
408
|
#
|
404
|
-
#
|
409
|
+
# == Customizing the query
|
410
|
+
#
|
411
|
+
# Associations are built from <tt>Relation</tt>s, and you can use the <tt>Relation</tt> syntax
|
412
|
+
# to customize them. For example, to add a condition:
|
413
|
+
#
|
414
|
+
# class Blog < ActiveRecord::Base
|
415
|
+
# has_many :published_posts, -> { where published: true }, class_name: 'Post'
|
416
|
+
# end
|
417
|
+
#
|
418
|
+
# Inside the <tt>-> { ... }</tt> block you can use all of the usual <tt>Relation</tt> methods.
|
419
|
+
#
|
420
|
+
# === Accessing the owner object
|
421
|
+
#
|
422
|
+
# Sometimes it is useful to have access to the owner object when building the query. The owner
|
423
|
+
# is passed as a parameter to the block. For example, the following association would find all
|
424
|
+
# events that occur on the user's birthday:
|
425
|
+
#
|
426
|
+
# class User < ActiveRecord::Base
|
427
|
+
# has_many :birthday_events, ->(user) { where starts_on: user.birthday }, class_name: 'Event'
|
428
|
+
# end
|
429
|
+
#
|
430
|
+
# == Association callbacks
|
405
431
|
#
|
406
432
|
# Similar to the normal callbacks that hook into the life cycle of an Active Record object,
|
407
433
|
# you can also define callbacks that get triggered when you add an object to or remove an
|
408
434
|
# object from an association collection.
|
409
435
|
#
|
410
436
|
# class Project
|
411
|
-
# has_and_belongs_to_many :developers, :
|
437
|
+
# has_and_belongs_to_many :developers, after_add: :evaluate_velocity
|
412
438
|
#
|
413
439
|
# def evaluate_velocity(developer)
|
414
440
|
# ...
|
@@ -419,7 +445,7 @@ module ActiveRecord
|
|
419
445
|
#
|
420
446
|
# class Project
|
421
447
|
# has_and_belongs_to_many :developers,
|
422
|
-
# :
|
448
|
+
# after_add: [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
|
423
449
|
# end
|
424
450
|
#
|
425
451
|
# Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
|
@@ -428,7 +454,7 @@ module ActiveRecord
|
|
428
454
|
# added to the collection. Same with the +before_remove+ callbacks; if an exception is
|
429
455
|
# thrown the object doesn't get removed.
|
430
456
|
#
|
431
|
-
#
|
457
|
+
# == Association extensions
|
432
458
|
#
|
433
459
|
# The proxy objects that control the access to associations can be extended through anonymous
|
434
460
|
# modules. This is especially beneficial for adding new finders, creators, and other
|
@@ -438,7 +464,7 @@ module ActiveRecord
|
|
438
464
|
# has_many :people do
|
439
465
|
# def find_or_create_by_name(name)
|
440
466
|
# first_name, last_name = name.split(" ", 2)
|
441
|
-
#
|
467
|
+
# find_or_create_by(first_name: first_name, last_name: last_name)
|
442
468
|
# end
|
443
469
|
# end
|
444
470
|
# end
|
@@ -453,25 +479,16 @@ module ActiveRecord
|
|
453
479
|
# module FindOrCreateByNameExtension
|
454
480
|
# def find_or_create_by_name(name)
|
455
481
|
# first_name, last_name = name.split(" ", 2)
|
456
|
-
#
|
482
|
+
# find_or_create_by(first_name: first_name, last_name: last_name)
|
457
483
|
# end
|
458
484
|
# end
|
459
485
|
#
|
460
486
|
# class Account < ActiveRecord::Base
|
461
|
-
# has_many :people,
|
487
|
+
# has_many :people, -> { extending FindOrCreateByNameExtension }
|
462
488
|
# end
|
463
489
|
#
|
464
490
|
# class Company < ActiveRecord::Base
|
465
|
-
# has_many :people,
|
466
|
-
# end
|
467
|
-
#
|
468
|
-
# If you need to use multiple named extension modules, you can specify an array of modules
|
469
|
-
# with the <tt>:extend</tt> option.
|
470
|
-
# In the case of name conflicts between methods in the modules, methods in modules later
|
471
|
-
# in the array supercede those earlier in the array.
|
472
|
-
#
|
473
|
-
# class Account < ActiveRecord::Base
|
474
|
-
# has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension]
|
491
|
+
# has_many :people, -> { extending FindOrCreateByNameExtension }
|
475
492
|
# end
|
476
493
|
#
|
477
494
|
# Some extensions can only be made to work with knowledge of the association's internals.
|
@@ -489,7 +506,7 @@ module ActiveRecord
|
|
489
506
|
# the same object, allowing you to make calls like <tt>proxy_association.owner</tt> inside
|
490
507
|
# association extensions.
|
491
508
|
#
|
492
|
-
#
|
509
|
+
# == Association Join Models
|
493
510
|
#
|
494
511
|
# Has Many associations can be configured with the <tt>:through</tt> option to use an
|
495
512
|
# explicit join model to retrieve the data. This operates similarly to a
|
@@ -498,7 +515,7 @@ module ActiveRecord
|
|
498
515
|
#
|
499
516
|
# class Author < ActiveRecord::Base
|
500
517
|
# has_many :authorships
|
501
|
-
# has_many :books, :
|
518
|
+
# has_many :books, through: :authorships
|
502
519
|
# end
|
503
520
|
#
|
504
521
|
# class Authorship < ActiveRecord::Base
|
@@ -514,7 +531,7 @@ module ActiveRecord
|
|
514
531
|
#
|
515
532
|
# class Firm < ActiveRecord::Base
|
516
533
|
# has_many :clients
|
517
|
-
# has_many :invoices, :
|
534
|
+
# has_many :invoices, through: :clients
|
518
535
|
# end
|
519
536
|
#
|
520
537
|
# class Client < ActiveRecord::Base
|
@@ -534,7 +551,7 @@ module ActiveRecord
|
|
534
551
|
#
|
535
552
|
# class Group < ActiveRecord::Base
|
536
553
|
# has_many :users
|
537
|
-
# has_many :avatars, :
|
554
|
+
# has_many :avatars, through: :users
|
538
555
|
# end
|
539
556
|
#
|
540
557
|
# class User < ActiveRecord::Base
|
@@ -547,7 +564,7 @@ module ActiveRecord
|
|
547
564
|
# end
|
548
565
|
#
|
549
566
|
# @group = Group.first
|
550
|
-
# @group.users.collect { |u| u.avatar }.
|
567
|
+
# @group.users.collect { |u| u.avatar }.compact # select all avatars for all users in the group
|
551
568
|
# @group.avatars # selects all avatars by going through the User join model.
|
552
569
|
#
|
553
570
|
# An important caveat with going through +has_one+ or +has_many+ associations on the
|
@@ -562,7 +579,7 @@ module ActiveRecord
|
|
562
579
|
# works correctly (where <tt>tags</tt> is a +has_many+ <tt>:through</tt> association):
|
563
580
|
#
|
564
581
|
# @post = Post.first
|
565
|
-
# @tag = @post.tags.build :
|
582
|
+
# @tag = @post.tags.build name: "ruby"
|
566
583
|
# @tag.save
|
567
584
|
#
|
568
585
|
# The last line ought to save the through record (a <tt>Taggable</tt>). This will only work if the
|
@@ -570,18 +587,18 @@ module ActiveRecord
|
|
570
587
|
#
|
571
588
|
# class Taggable < ActiveRecord::Base
|
572
589
|
# belongs_to :post
|
573
|
-
# belongs_to :tag, :
|
590
|
+
# belongs_to :tag, inverse_of: :taggings
|
574
591
|
# end
|
575
592
|
#
|
576
|
-
#
|
593
|
+
# == Nested Associations
|
577
594
|
#
|
578
595
|
# You can actually specify *any* association with the <tt>:through</tt> option, including an
|
579
596
|
# association which has a <tt>:through</tt> option itself. For example:
|
580
597
|
#
|
581
598
|
# class Author < ActiveRecord::Base
|
582
599
|
# has_many :posts
|
583
|
-
# has_many :comments, :
|
584
|
-
# has_many :commenters, :
|
600
|
+
# has_many :comments, through: :posts
|
601
|
+
# has_many :commenters, through: :comments
|
585
602
|
# end
|
586
603
|
#
|
587
604
|
# class Post < ActiveRecord::Base
|
@@ -599,12 +616,12 @@ module ActiveRecord
|
|
599
616
|
#
|
600
617
|
# class Author < ActiveRecord::Base
|
601
618
|
# has_many :posts
|
602
|
-
# has_many :commenters, :
|
619
|
+
# has_many :commenters, through: :posts
|
603
620
|
# end
|
604
621
|
#
|
605
622
|
# class Post < ActiveRecord::Base
|
606
623
|
# has_many :comments
|
607
|
-
# has_many :commenters, :
|
624
|
+
# has_many :commenters, through: :comments
|
608
625
|
# end
|
609
626
|
#
|
610
627
|
# class Comment < ActiveRecord::Base
|
@@ -616,18 +633,18 @@ module ActiveRecord
|
|
616
633
|
# add a <tt>Commenter</tt> in the example above, there would be no way to tell how to set up the
|
617
634
|
# intermediate <tt>Post</tt> and <tt>Comment</tt> objects.
|
618
635
|
#
|
619
|
-
#
|
636
|
+
# == Polymorphic Associations
|
620
637
|
#
|
621
638
|
# Polymorphic associations on models are not restricted on what types of models they
|
622
639
|
# can be associated with. Rather, they specify an interface that a +has_many+ association
|
623
640
|
# must adhere to.
|
624
641
|
#
|
625
642
|
# class Asset < ActiveRecord::Base
|
626
|
-
# belongs_to :attachable, :
|
643
|
+
# belongs_to :attachable, polymorphic: true
|
627
644
|
# end
|
628
645
|
#
|
629
646
|
# class Post < ActiveRecord::Base
|
630
|
-
# has_many :assets, :
|
647
|
+
# has_many :assets, as: :attachable # The :as option specifies the polymorphic interface to use.
|
631
648
|
# end
|
632
649
|
#
|
633
650
|
# @asset.attachable = @post
|
@@ -644,16 +661,16 @@ module ActiveRecord
|
|
644
661
|
# column in the posts table.
|
645
662
|
#
|
646
663
|
# class Asset < ActiveRecord::Base
|
647
|
-
# belongs_to :attachable, :
|
664
|
+
# belongs_to :attachable, polymorphic: true
|
648
665
|
#
|
649
|
-
# def attachable_type=(
|
650
|
-
# super(
|
666
|
+
# def attachable_type=(klass)
|
667
|
+
# super(klass.to_s.classify.constantize.base_class.to_s)
|
651
668
|
# end
|
652
669
|
# end
|
653
670
|
#
|
654
671
|
# class Post < ActiveRecord::Base
|
655
|
-
# # because we store "Post" in attachable_type now :
|
656
|
-
# has_many :assets, :
|
672
|
+
# # because we store "Post" in attachable_type now dependent: :destroy will work
|
673
|
+
# has_many :assets, as: :attachable, dependent: :destroy
|
657
674
|
# end
|
658
675
|
#
|
659
676
|
# class GuestPost < Post
|
@@ -715,7 +732,7 @@ module ActiveRecord
|
|
715
732
|
#
|
716
733
|
# To include a deep hierarchy of associations, use a hash:
|
717
734
|
#
|
718
|
-
# Post.includes(:author, {:
|
735
|
+
# Post.includes(:author, {comments: {author: :gravatar}}).each do |post|
|
719
736
|
#
|
720
737
|
# That'll grab not only all the comments but all their authors and gravatar pictures.
|
721
738
|
# You can mix and match symbols, arrays and hashes in any combination to describe the
|
@@ -731,7 +748,7 @@ module ActiveRecord
|
|
731
748
|
# other than the main one. If this is the case Active Record falls back to the previously
|
732
749
|
# used LEFT OUTER JOIN based strategy. For example
|
733
750
|
#
|
734
|
-
# Post.includes([:author, :comments]).where(['comments.approved = ?', true])
|
751
|
+
# Post.includes([:author, :comments]).where(['comments.approved = ?', true])
|
735
752
|
#
|
736
753
|
# This will result in a single SQL query with joins along the lines of:
|
737
754
|
# <tt>LEFT OUTER JOIN comments ON comments.post_id = posts.id</tt> and
|
@@ -740,13 +757,13 @@ module ActiveRecord
|
|
740
757
|
# In the above example posts with no approved comments are not returned at all, because
|
741
758
|
# the conditions apply to the SQL statement as a whole and not just to the association.
|
742
759
|
# You must disambiguate column references for this fallback to happen, for example
|
743
|
-
# <tt
|
760
|
+
# <tt>order: "author.name DESC"</tt> will work but <tt>order: "name DESC"</tt> will not.
|
744
761
|
#
|
745
762
|
# If you do want eager load only some members of an association it is usually more natural
|
746
763
|
# to include an association which has conditions defined on it:
|
747
764
|
#
|
748
765
|
# class Post < ActiveRecord::Base
|
749
|
-
# has_many :approved_comments,
|
766
|
+
# has_many :approved_comments, -> { where approved: true }, class_name: 'Comment'
|
750
767
|
# end
|
751
768
|
#
|
752
769
|
# Post.includes(:approved_comments)
|
@@ -758,18 +775,15 @@ module ActiveRecord
|
|
758
775
|
# returning all the associated objects:
|
759
776
|
#
|
760
777
|
# class Picture < ActiveRecord::Base
|
761
|
-
# has_many :most_recent_comments,
|
778
|
+
# has_many :most_recent_comments, -> { order('id DESC').limit(10) }, class_name: 'Comment'
|
762
779
|
# end
|
763
780
|
#
|
764
781
|
# Picture.includes(:most_recent_comments).first.most_recent_comments # => returns all associated comments.
|
765
782
|
#
|
766
|
-
# When eager loaded, conditions are interpolated in the context of the model class, not
|
767
|
-
# the model instance. Conditions are lazily interpolated before the actual model exists.
|
768
|
-
#
|
769
783
|
# Eager loading is supported with polymorphic associations.
|
770
784
|
#
|
771
785
|
# class Address < ActiveRecord::Base
|
772
|
-
# belongs_to :addressable, :
|
786
|
+
# belongs_to :addressable, polymorphic: true
|
773
787
|
# end
|
774
788
|
#
|
775
789
|
# A call that tries to eager load the addressable model
|
@@ -803,10 +817,10 @@ module ActiveRecord
|
|
803
817
|
#
|
804
818
|
# TreeMixin.joins(:children)
|
805
819
|
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
|
806
|
-
# TreeMixin.joins(:
|
820
|
+
# TreeMixin.joins(children: :parent)
|
807
821
|
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
|
808
822
|
# INNER JOIN parents_mixins ...
|
809
|
-
# TreeMixin.joins(:
|
823
|
+
# TreeMixin.joins(children: {parent: :children})
|
810
824
|
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
|
811
825
|
# INNER JOIN parents_mixins ...
|
812
826
|
# INNER JOIN mixins childrens_mixins_2
|
@@ -815,10 +829,10 @@ module ActiveRecord
|
|
815
829
|
#
|
816
830
|
# Post.joins(:categories)
|
817
831
|
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
|
818
|
-
# Post.joins(:
|
832
|
+
# Post.joins(categories: :posts)
|
819
833
|
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
|
820
834
|
# INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
|
821
|
-
# Post.joins(:
|
835
|
+
# Post.joins(categories: {posts: :categories})
|
822
836
|
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
|
823
837
|
# INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
|
824
838
|
# INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
|
@@ -843,8 +857,8 @@ module ActiveRecord
|
|
843
857
|
# module MyApplication
|
844
858
|
# module Business
|
845
859
|
# class Firm < ActiveRecord::Base
|
846
|
-
#
|
847
|
-
#
|
860
|
+
# has_many :clients
|
861
|
+
# end
|
848
862
|
#
|
849
863
|
# class Client < ActiveRecord::Base; end
|
850
864
|
# end
|
@@ -862,7 +876,7 @@ module ActiveRecord
|
|
862
876
|
#
|
863
877
|
# module Billing
|
864
878
|
# class Account < ActiveRecord::Base
|
865
|
-
# belongs_to :firm, :
|
879
|
+
# belongs_to :firm, class_name: "MyApplication::Business::Firm"
|
866
880
|
# end
|
867
881
|
# end
|
868
882
|
# end
|
@@ -904,16 +918,16 @@ module ActiveRecord
|
|
904
918
|
# example, if we changed our model definitions to:
|
905
919
|
#
|
906
920
|
# class Dungeon < ActiveRecord::Base
|
907
|
-
# has_many :traps, :
|
908
|
-
# has_one :evil_wizard, :
|
921
|
+
# has_many :traps, inverse_of: :dungeon
|
922
|
+
# has_one :evil_wizard, inverse_of: :dungeon
|
909
923
|
# end
|
910
924
|
#
|
911
925
|
# class Trap < ActiveRecord::Base
|
912
|
-
# belongs_to :dungeon, :
|
926
|
+
# belongs_to :dungeon, inverse_of: :traps
|
913
927
|
# end
|
914
928
|
#
|
915
929
|
# class EvilWizard < ActiveRecord::Base
|
916
|
-
# belongs_to :dungeon, :
|
930
|
+
# belongs_to :dungeon, inverse_of: :evil_wizard
|
917
931
|
# end
|
918
932
|
#
|
919
933
|
# Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same
|
@@ -936,13 +950,19 @@ module ActiveRecord
|
|
936
950
|
# For example:
|
937
951
|
#
|
938
952
|
# class Author
|
939
|
-
# has_many :posts, :
|
953
|
+
# has_many :posts, dependent: :destroy
|
940
954
|
# end
|
941
955
|
# Author.find(1).destroy # => Will destroy all of the author's posts, too
|
942
956
|
#
|
943
957
|
# The <tt>:dependent</tt> option can have different values which specify how the deletion
|
944
958
|
# is done. For more information, see the documentation for this option on the different
|
945
|
-
# specific association types.
|
959
|
+
# specific association types. When no option is given, the behavior is to do nothing
|
960
|
+
# with the associated records when destroying a record.
|
961
|
+
#
|
962
|
+
# Note that <tt>:dependent</tt> is implemented using Rails' callback
|
963
|
+
# system, which works by processing callbacks in order. Therefore, other
|
964
|
+
# callbacks declared either before or after the <tt>:dependent</tt> option
|
965
|
+
# can affect what it does.
|
946
966
|
#
|
947
967
|
# === Delete or destroy?
|
948
968
|
#
|
@@ -952,8 +972,8 @@ module ActiveRecord
|
|
952
972
|
# For +has_and_belongs_to_many+, <tt>delete</tt> and <tt>destroy</tt> are the same: they
|
953
973
|
# cause the records in the join table to be removed.
|
954
974
|
#
|
955
|
-
# For +has_many+, <tt>destroy</tt> will always call the <tt>destroy</tt> method of the
|
956
|
-
# record(s) being removed so that callbacks are run. However <tt>delete</tt> will either
|
975
|
+
# For +has_many+, <tt>destroy</tt> and <tt>destroy_all</tt> will always call the <tt>destroy</tt> method of the
|
976
|
+
# record(s) being removed so that callbacks are run. However <tt>delete</tt> and <tt>delete_all</tt> will either
|
957
977
|
# do the deletion according to the strategy specified by the <tt>:dependent</tt> option, or
|
958
978
|
# if no <tt>:dependent</tt> option is given, then it will follow the default strategy.
|
959
979
|
# The default strategy is <tt>:nullify</tt> (set the foreign keys to <tt>nil</tt>), except for
|
@@ -974,7 +994,7 @@ module ActiveRecord
|
|
974
994
|
# associated objects themselves. So with +has_and_belongs_to_many+ and +has_many+
|
975
995
|
# <tt>:through</tt>, the join records will be deleted, but the associated records won't.
|
976
996
|
#
|
977
|
-
# This makes sense if you think about it: if you were to call <tt>post.tags.delete(Tag.
|
997
|
+
# This makes sense if you think about it: if you were to call <tt>post.tags.delete(Tag.find_by(name: 'food'))</tt>
|
978
998
|
# you would want the 'food' tag to be unlinked from the post, rather than for the tag itself
|
979
999
|
# to be removed from the database.
|
980
1000
|
#
|
@@ -1011,15 +1031,21 @@ module ActiveRecord
|
|
1011
1031
|
# [collection<<(object, ...)]
|
1012
1032
|
# Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
|
1013
1033
|
# Note that this operation instantly fires update sql without waiting for the save or update call on the
|
1014
|
-
# parent object.
|
1034
|
+
# parent object, unless the parent object is a new record.
|
1015
1035
|
# [collection.delete(object, ...)]
|
1016
1036
|
# Removes one or more objects from the collection by setting their foreign keys to +NULL+.
|
1017
|
-
# Objects will be in addition destroyed if they're associated with <tt
|
1018
|
-
# and deleted if they're associated with <tt
|
1037
|
+
# Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
|
1038
|
+
# and deleted if they're associated with <tt>dependent: :delete_all</tt>.
|
1019
1039
|
#
|
1020
1040
|
# If the <tt>:through</tt> option is used, then the join records are deleted (rather than
|
1021
|
-
# nullified) by default, but you can specify <tt
|
1022
|
-
# <tt
|
1041
|
+
# nullified) by default, but you can specify <tt>dependent: :destroy</tt> or
|
1042
|
+
# <tt>dependent: :nullify</tt> to override this.
|
1043
|
+
# [collection.destroy(object, ...)]
|
1044
|
+
# Removes one or more objects from the collection by running <tt>destroy</tt> on
|
1045
|
+
# each record, regardless of any dependent option, ensuring callbacks are run.
|
1046
|
+
#
|
1047
|
+
# If the <tt>:through</tt> option is used, then the join records are destroyed
|
1048
|
+
# instead, not the objects themselves.
|
1023
1049
|
# [collection=objects]
|
1024
1050
|
# Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
|
1025
1051
|
# option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
|
@@ -1031,8 +1057,8 @@ module ActiveRecord
|
|
1031
1057
|
# method loads the models and calls <tt>collection=</tt>. See above.
|
1032
1058
|
# [collection.clear]
|
1033
1059
|
# Removes every object from the collection. This destroys the associated objects if they
|
1034
|
-
# are associated with <tt
|
1035
|
-
# database if <tt
|
1060
|
+
# are associated with <tt>dependent: :destroy</tt>, deletes them directly from the
|
1061
|
+
# database if <tt>dependent: :delete_all</tt>, otherwise sets their foreign keys to +NULL+.
|
1036
1062
|
# If the <tt>:through</tt> option is true no destroy callbacks are invoked on the join models.
|
1037
1063
|
# Join models are directly deleted.
|
1038
1064
|
# [collection.empty?]
|
@@ -1053,6 +1079,9 @@ module ActiveRecord
|
|
1053
1079
|
# with +attributes+, linked to this object through a foreign key, and that has already
|
1054
1080
|
# been saved (if it passed the validation). *Note*: This only works if the base model
|
1055
1081
|
# already exists in the DB, not if it is a new (unsaved) record!
|
1082
|
+
# [collection.create!(attributes = {})]
|
1083
|
+
# Does the same as <tt>collection.create</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt>
|
1084
|
+
# if the record is invalid.
|
1056
1085
|
#
|
1057
1086
|
# (*Note*: +collection+ is replaced with the symbol passed as the first argument, so
|
1058
1087
|
# <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.)
|
@@ -1060,19 +1089,21 @@ module ActiveRecord
|
|
1060
1089
|
# === Example
|
1061
1090
|
#
|
1062
1091
|
# Example: A Firm class declares <tt>has_many :clients</tt>, which will add:
|
1063
|
-
# * <tt>Firm#clients</tt> (similar to <tt>
|
1092
|
+
# * <tt>Firm#clients</tt> (similar to <tt>Client.where(firm_id: id)</tt>)
|
1064
1093
|
# * <tt>Firm#clients<<</tt>
|
1065
1094
|
# * <tt>Firm#clients.delete</tt>
|
1095
|
+
# * <tt>Firm#clients.destroy</tt>
|
1066
1096
|
# * <tt>Firm#clients=</tt>
|
1067
1097
|
# * <tt>Firm#client_ids</tt>
|
1068
1098
|
# * <tt>Firm#client_ids=</tt>
|
1069
1099
|
# * <tt>Firm#clients.clear</tt>
|
1070
1100
|
# * <tt>Firm#clients.empty?</tt> (similar to <tt>firm.clients.size == 0</tt>)
|
1071
1101
|
# * <tt>Firm#clients.size</tt> (similar to <tt>Client.count "firm_id = #{id}"</tt>)
|
1072
|
-
# * <tt>Firm#clients.find</tt> (similar to <tt>Client.
|
1073
|
-
# * <tt>Firm#clients.exists?(:
|
1102
|
+
# * <tt>Firm#clients.find</tt> (similar to <tt>Client.where(firm_id: id).find(id)</tt>)
|
1103
|
+
# * <tt>Firm#clients.exists?(name: 'ACME')</tt> (similar to <tt>Client.exists?(name: 'ACME', firm_id: firm.id)</tt>)
|
1074
1104
|
# * <tt>Firm#clients.build</tt> (similar to <tt>Client.new("firm_id" => id)</tt>)
|
1075
1105
|
# * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save; c</tt>)
|
1106
|
+
# * <tt>Firm#clients.create!</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save!</tt>)
|
1076
1107
|
# The declaration can also include an options hash to specialize the behavior of the association.
|
1077
1108
|
#
|
1078
1109
|
# === Options
|
@@ -1081,15 +1112,6 @@ module ActiveRecord
|
|
1081
1112
|
# from the association name. So <tt>has_many :products</tt> will by default be linked
|
1082
1113
|
# to the Product class, but if the real class name is SpecialProduct, you'll have to
|
1083
1114
|
# specify it with this option.
|
1084
|
-
# [:conditions]
|
1085
|
-
# Specify the conditions that the associated objects must meet in order to be included as a +WHERE+
|
1086
|
-
# SQL fragment, such as <tt>price > 5 AND name LIKE 'B%'</tt>. Record creations from
|
1087
|
-
# the association are scoped if a hash is used.
|
1088
|
-
# <tt>has_many :posts, :conditions => {:published => true}</tt> will create published
|
1089
|
-
# posts with <tt>@blog.posts.create</tt> or <tt>@blog.posts.build</tt>.
|
1090
|
-
# [:order]
|
1091
|
-
# Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
|
1092
|
-
# such as <tt>last_name, first_name DESC</tt>.
|
1093
1115
|
# [:foreign_key]
|
1094
1116
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1095
1117
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+
|
@@ -1097,44 +1119,24 @@ module ActiveRecord
|
|
1097
1119
|
# [:primary_key]
|
1098
1120
|
# Specify the method that returns the primary key used for the association. By default this is +id+.
|
1099
1121
|
# [:dependent]
|
1100
|
-
#
|
1101
|
-
#
|
1102
|
-
#
|
1103
|
-
#
|
1104
|
-
#
|
1105
|
-
#
|
1122
|
+
# Controls what happens to the associated objects when
|
1123
|
+
# their owner is destroyed. Note that these are implemented as
|
1124
|
+
# callbacks, and Rails executes callbacks in order. Therefore, other
|
1125
|
+
# similar callbacks may affect the :dependent behavior, and the
|
1126
|
+
# :dependent behavior may affect other callbacks.
|
1127
|
+
#
|
1128
|
+
# * <tt>:destroy</tt> causes all the associated objects to also be destroyed.
|
1129
|
+
# * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
|
1130
|
+
# * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Callbacks are not executed.
|
1131
|
+
# * <tt>:restrict_with_exception</tt> causes an exception to be raised if there are any associated records.
|
1132
|
+
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
|
1106
1133
|
#
|
1107
1134
|
# If using with the <tt>:through</tt> option, the association on the join model must be
|
1108
1135
|
# a +belongs_to+, and the records which get deleted are the join records, rather than
|
1109
1136
|
# the associated records.
|
1110
|
-
#
|
1111
|
-
#
|
1112
|
-
#
|
1113
|
-
# associations that depend on multiple tables. May be supplied as a string or a proc where interpolation is
|
1114
|
-
# required. Note: When this option is used, +find_in_collection+
|
1115
|
-
# is _not_ added.
|
1116
|
-
# [:counter_sql]
|
1117
|
-
# Specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is
|
1118
|
-
# specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by
|
1119
|
-
# replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>.
|
1120
|
-
# [:extend]
|
1121
|
-
# Specify a named module for extending the proxy. See "Association extensions".
|
1122
|
-
# [:include]
|
1123
|
-
# Specify second-order associations that should be eager loaded when the collection is loaded.
|
1124
|
-
# [:group]
|
1125
|
-
# An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
|
1126
|
-
# [:having]
|
1127
|
-
# Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt>
|
1128
|
-
# returns. Uses the <tt>HAVING</tt> SQL-clause.
|
1129
|
-
# [:limit]
|
1130
|
-
# An integer determining the limit on the number of rows that should be returned.
|
1131
|
-
# [:offset]
|
1132
|
-
# An integer determining the offset from where the rows should be fetched. So at 5,
|
1133
|
-
# it would skip the first 4 rows.
|
1134
|
-
# [:select]
|
1135
|
-
# By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if
|
1136
|
-
# you, for example, want to do a join but not include the joined columns. Do not forget
|
1137
|
-
# to include the primary and foreign keys, otherwise it will raise an error.
|
1137
|
+
# [:counter_cache]
|
1138
|
+
# This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option,
|
1139
|
+
# when you customized the name of your <tt>:counter_cache</tt> on the <tt>belongs_to</tt> association.
|
1138
1140
|
# [:as]
|
1139
1141
|
# Specifies a polymorphic interface (See <tt>belongs_to</tt>).
|
1140
1142
|
# [:through]
|
@@ -1156,21 +1158,21 @@ module ActiveRecord
|
|
1156
1158
|
# [:source]
|
1157
1159
|
# Specifies the source association name used by <tt>has_many :through</tt> queries.
|
1158
1160
|
# Only use it if the name cannot be inferred from the association.
|
1159
|
-
# <tt>has_many :subscribers, :
|
1161
|
+
# <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
|
1160
1162
|
# <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
|
1161
1163
|
# [:source_type]
|
1162
1164
|
# Specifies type of the source association used by <tt>has_many :through</tt> queries where the source
|
1163
1165
|
# association is a polymorphic +belongs_to+.
|
1164
|
-
# [:uniq]
|
1165
|
-
# If true, duplicates will be omitted from the collection. Useful in conjunction with <tt>:through</tt>.
|
1166
|
-
# [:readonly]
|
1167
|
-
# If true, all the associated objects are readonly through the association.
|
1168
1166
|
# [:validate]
|
1169
1167
|
# If +false+, don't validate the associated objects when saving the parent object. true by default.
|
1170
1168
|
# [:autosave]
|
1171
1169
|
# If true, always save the associated objects or destroy them if marked for destruction,
|
1172
1170
|
# when saving the parent object. If false, never save or destroy the associated objects.
|
1173
|
-
# By default, only save associated objects that are new records.
|
1171
|
+
# By default, only save associated objects that are new records. This option is implemented as a
|
1172
|
+
# before_save callback. Because callbacks are run in the order they are defined, associated objects
|
1173
|
+
# may need to be explicitly saved in any user-defined before_save callbacks.
|
1174
|
+
#
|
1175
|
+
# Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
|
1174
1176
|
# [:inverse_of]
|
1175
1177
|
# Specifies the name of the <tt>belongs_to</tt> association on the associated object
|
1176
1178
|
# that is the inverse of this <tt>has_many</tt> association. Does not work in combination
|
@@ -1178,24 +1180,16 @@ module ActiveRecord
|
|
1178
1180
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1179
1181
|
#
|
1180
1182
|
# Option examples:
|
1181
|
-
# has_many :comments,
|
1182
|
-
# has_many :comments,
|
1183
|
-
# has_many :people,
|
1184
|
-
# has_many :tracks,
|
1185
|
-
# has_many :comments, :
|
1186
|
-
# has_many :tags, :
|
1187
|
-
# has_many :reports,
|
1188
|
-
# has_many :subscribers, :
|
1189
|
-
|
1190
|
-
|
1191
|
-
# SELECT DISTINCT *
|
1192
|
-
# FROM people p, post_subscriptions ps
|
1193
|
-
# WHERE ps.post_id = #{id} AND ps.person_id = p.id
|
1194
|
-
# ORDER BY p.first_name
|
1195
|
-
# }
|
1196
|
-
# }
|
1197
|
-
def has_many(name, options = {}, &extension)
|
1198
|
-
Builder::HasMany.build(self, name, options, &extension)
|
1183
|
+
# has_many :comments, -> { order "posted_on" }
|
1184
|
+
# has_many :comments, -> { includes :author }
|
1185
|
+
# has_many :people, -> { where("deleted = 0").order("name") }, class_name: "Person"
|
1186
|
+
# has_many :tracks, -> { order "position" }, dependent: :destroy
|
1187
|
+
# has_many :comments, dependent: :nullify
|
1188
|
+
# has_many :tags, as: :taggable
|
1189
|
+
# has_many :reports, -> { readonly }
|
1190
|
+
# has_many :subscribers, through: :subscriptions, source: :user
|
1191
|
+
def has_many(name, scope = nil, options = {}, &extension)
|
1192
|
+
Builder::HasMany.build(self, name, scope, options, &extension)
|
1199
1193
|
end
|
1200
1194
|
|
1201
1195
|
# Specifies a one-to-one association with another class. This method should only be used
|
@@ -1228,7 +1222,7 @@ module ActiveRecord
|
|
1228
1222
|
# === Example
|
1229
1223
|
#
|
1230
1224
|
# An Account class declares <tt>has_one :beneficiary</tt>, which will add:
|
1231
|
-
# * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.
|
1225
|
+
# * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.where(account_id: id).first</tt>)
|
1232
1226
|
# * <tt>Account#beneficiary=(beneficiary)</tt> (similar to <tt>beneficiary.account_id = account.id; beneficiary.save</tt>)
|
1233
1227
|
# * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new("account_id" => id)</tt>)
|
1234
1228
|
# * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save; b</tt>)
|
@@ -1243,34 +1237,23 @@ module ActiveRecord
|
|
1243
1237
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1244
1238
|
# from the association name. So <tt>has_one :manager</tt> will by default be linked to the Manager class, but
|
1245
1239
|
# if the real class name is Person, you'll have to specify it with this option.
|
1246
|
-
# [:conditions]
|
1247
|
-
# Specify the conditions that the associated object must meet in order to be included as a +WHERE+
|
1248
|
-
# SQL fragment, such as <tt>rank = 5</tt>. Record creation from the association is scoped if a hash
|
1249
|
-
# is used. <tt>has_one :account, :conditions => {:enabled => true}</tt> will create
|
1250
|
-
# an enabled account with <tt>@company.create_account</tt> or <tt>@company.build_account</tt>.
|
1251
|
-
# [:order]
|
1252
|
-
# Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
|
1253
|
-
# such as <tt>last_name, first_name DESC</tt>.
|
1254
1240
|
# [:dependent]
|
1255
|
-
#
|
1256
|
-
#
|
1257
|
-
#
|
1258
|
-
#
|
1259
|
-
# <tt
|
1241
|
+
# Controls what happens to the associated object when
|
1242
|
+
# its owner is destroyed:
|
1243
|
+
#
|
1244
|
+
# * <tt>:destroy</tt> causes the associated object to also be destroyed
|
1245
|
+
# * <tt>:delete</tt> causes the associated object to be deleted directly from the database (so callbacks will not execute)
|
1246
|
+
# * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Callbacks are not executed.
|
1247
|
+
# * <tt>:restrict_with_exception</tt> causes an exception to be raised if there is an associated record
|
1248
|
+
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
|
1260
1249
|
# [:foreign_key]
|
1261
1250
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1262
1251
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association
|
1263
1252
|
# will use "person_id" as the default <tt>:foreign_key</tt>.
|
1264
1253
|
# [:primary_key]
|
1265
1254
|
# Specify the method that returns the primary key used for the association. By default this is +id+.
|
1266
|
-
# [:include]
|
1267
|
-
# Specify second-order associations that should be eager loaded when this object is loaded.
|
1268
1255
|
# [:as]
|
1269
1256
|
# Specifies a polymorphic interface (See <tt>belongs_to</tt>).
|
1270
|
-
# [:select]
|
1271
|
-
# By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example,
|
1272
|
-
# you want to do a join but not include the joined columns. Do not forget to include the
|
1273
|
-
# primary and foreign keys, otherwise it will raise an error.
|
1274
1257
|
# [:through]
|
1275
1258
|
# Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>,
|
1276
1259
|
# <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
|
@@ -1279,19 +1262,19 @@ module ActiveRecord
|
|
1279
1262
|
# [:source]
|
1280
1263
|
# Specifies the source association name used by <tt>has_one :through</tt> queries.
|
1281
1264
|
# Only use it if the name cannot be inferred from the association.
|
1282
|
-
# <tt>has_one :favorite, :
|
1265
|
+
# <tt>has_one :favorite, through: :favorites</tt> will look for a
|
1283
1266
|
# <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
|
1284
1267
|
# [:source_type]
|
1285
1268
|
# Specifies type of the source association used by <tt>has_one :through</tt> queries where the source
|
1286
1269
|
# association is a polymorphic +belongs_to+.
|
1287
|
-
# [:readonly]
|
1288
|
-
# If true, the associated object is readonly through the association.
|
1289
1270
|
# [:validate]
|
1290
1271
|
# If +false+, don't validate the associated object when saving the parent object. +false+ by default.
|
1291
1272
|
# [:autosave]
|
1292
1273
|
# If true, always save the associated object or destroy it if marked for destruction,
|
1293
1274
|
# when saving the parent object. If false, never save or destroy the associated object.
|
1294
1275
|
# By default, only save the associated object if it's a new record.
|
1276
|
+
#
|
1277
|
+
# Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
|
1295
1278
|
# [:inverse_of]
|
1296
1279
|
# Specifies the name of the <tt>belongs_to</tt> association on the associated object
|
1297
1280
|
# that is the inverse of this <tt>has_one</tt> association. Does not work in combination
|
@@ -1299,17 +1282,17 @@ module ActiveRecord
|
|
1299
1282
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1300
1283
|
#
|
1301
1284
|
# Option examples:
|
1302
|
-
# has_one :credit_card, :
|
1303
|
-
# has_one :credit_card, :
|
1285
|
+
# has_one :credit_card, dependent: :destroy # destroys the associated credit card
|
1286
|
+
# has_one :credit_card, dependent: :nullify # updates the associated records foreign
|
1304
1287
|
# # key value to NULL rather than destroying it
|
1305
|
-
# has_one :last_comment,
|
1306
|
-
# has_one :project_manager,
|
1307
|
-
# has_one :attachment, :
|
1308
|
-
# has_one :boss, :
|
1309
|
-
# has_one :club, :
|
1310
|
-
# has_one :primary_address,
|
1311
|
-
def has_one(name, options = {})
|
1312
|
-
Builder::HasOne.build(self, name, options)
|
1288
|
+
# has_one :last_comment, -> { order 'posted_on' }, class_name: "Comment"
|
1289
|
+
# has_one :project_manager, -> { where role: 'project_manager' }, class_name: "Person"
|
1290
|
+
# has_one :attachment, as: :attachable
|
1291
|
+
# has_one :boss, readonly: :true
|
1292
|
+
# has_one :club, through: :membership
|
1293
|
+
# has_one :primary_address, -> { where primary: true }, through: :addressables, source: :addressable
|
1294
|
+
def has_one(name, scope = nil, options = {})
|
1295
|
+
Builder::HasOne.build(self, name, scope, options)
|
1313
1296
|
end
|
1314
1297
|
|
1315
1298
|
# Specifies a one-to-one association with another class. This method should only be used
|
@@ -1354,23 +1337,16 @@ module ActiveRecord
|
|
1354
1337
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1355
1338
|
# from the association name. So <tt>belongs_to :author</tt> will by default be linked to the Author class, but
|
1356
1339
|
# if the real class name is Person, you'll have to specify it with this option.
|
1357
|
-
# [:conditions]
|
1358
|
-
# Specify the conditions that the associated object must meet in order to be included as a +WHERE+
|
1359
|
-
# SQL fragment, such as <tt>authorized = 1</tt>.
|
1360
|
-
# [:select]
|
1361
|
-
# By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed
|
1362
|
-
# if, for example, you want to do a join but not include the joined columns. Do not
|
1363
|
-
# forget to include the primary and foreign keys, otherwise it will raise an error.
|
1364
1340
|
# [:foreign_key]
|
1365
1341
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1366
1342
|
# of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt>
|
1367
1343
|
# association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
|
1368
|
-
# <tt>belongs_to :favorite_person, :
|
1344
|
+
# <tt>belongs_to :favorite_person, class_name: "Person"</tt> will use a foreign key
|
1369
1345
|
# of "favorite_person_id".
|
1370
1346
|
# [:foreign_type]
|
1371
1347
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
1372
1348
|
# association. By default this is guessed to be the name of the association with a "_type"
|
1373
|
-
# suffix. So a class that defines a <tt>belongs_to :taggable, :
|
1349
|
+
# suffix. So a class that defines a <tt>belongs_to :taggable, polymorphic: true</tt>
|
1374
1350
|
# association will use "taggable_type" as the default <tt>:foreign_type</tt>.
|
1375
1351
|
# [:primary_key]
|
1376
1352
|
# Specify the method that returns the primary key of associated object used for the association.
|
@@ -1386,19 +1362,17 @@ module ActiveRecord
|
|
1386
1362
|
# and +decrement_counter+. The counter cache is incremented when an object of this
|
1387
1363
|
# class is created and decremented when it's destroyed. This requires that a column
|
1388
1364
|
# named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class)
|
1389
|
-
# is used on the associate class (such as a Post class)
|
1365
|
+
# is used on the associate class (such as a Post class) - that is the migration for
|
1366
|
+
# <tt>#{table_name}_count</tt> is created on the associate class (such that Post.comments_count will
|
1367
|
+
# return the count cached, see note below). You can also specify a custom counter
|
1390
1368
|
# cache column by providing a column name instead of a +true+/+false+ value to this
|
1391
|
-
# option (e.g., <tt
|
1369
|
+
# option (e.g., <tt>counter_cache: :my_custom_counter</tt>.)
|
1392
1370
|
# Note: Specifying a counter cache will add it to that model's list of readonly attributes
|
1393
1371
|
# using +attr_readonly+.
|
1394
|
-
# [:include]
|
1395
|
-
# Specify second-order associations that should be eager loaded when this object is loaded.
|
1396
1372
|
# [:polymorphic]
|
1397
1373
|
# Specify this association is a polymorphic association by passing +true+.
|
1398
1374
|
# Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
|
1399
1375
|
# to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
|
1400
|
-
# [:readonly]
|
1401
|
-
# If true, the associated object is readonly through the association.
|
1402
1376
|
# [:validate]
|
1403
1377
|
# If +false+, don't validate the associated objects when saving the parent object. +false+ by default.
|
1404
1378
|
# [:autosave]
|
@@ -1406,6 +1380,8 @@ module ActiveRecord
|
|
1406
1380
|
# saving the parent object.
|
1407
1381
|
# If false, never save or destroy the associated object.
|
1408
1382
|
# By default, only save the associated object if it's a new record.
|
1383
|
+
#
|
1384
|
+
# Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
|
1409
1385
|
# [:touch]
|
1410
1386
|
# If true, the associated object will be touched (the updated_at/on attributes set to now)
|
1411
1387
|
# when this record is either saved or destroyed. If you specify a symbol, that attribute
|
@@ -1417,24 +1393,24 @@ module ActiveRecord
|
|
1417
1393
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1418
1394
|
#
|
1419
1395
|
# Option examples:
|
1420
|
-
# belongs_to :firm, :
|
1421
|
-
# belongs_to :person, :
|
1422
|
-
# belongs_to :author, :
|
1423
|
-
# belongs_to :valid_coupon,
|
1424
|
-
#
|
1425
|
-
# belongs_to :attachable, :
|
1426
|
-
# belongs_to :project, :
|
1427
|
-
# belongs_to :post, :
|
1428
|
-
# belongs_to :company, :
|
1429
|
-
# belongs_to :company, :
|
1430
|
-
def belongs_to(name, options = {})
|
1431
|
-
Builder::BelongsTo.build(self, name, options)
|
1396
|
+
# belongs_to :firm, foreign_key: "client_of"
|
1397
|
+
# belongs_to :person, primary_key: "name", foreign_key: "person_name"
|
1398
|
+
# belongs_to :author, class_name: "Person", foreign_key: "author_id"
|
1399
|
+
# belongs_to :valid_coupon, ->(o) { where "discounts > ?", o.payments_count },
|
1400
|
+
# class_name: "Coupon", foreign_key: "coupon_id"
|
1401
|
+
# belongs_to :attachable, polymorphic: true
|
1402
|
+
# belongs_to :project, readonly: true
|
1403
|
+
# belongs_to :post, counter_cache: true
|
1404
|
+
# belongs_to :company, touch: true
|
1405
|
+
# belongs_to :company, touch: :employees_last_updated_at
|
1406
|
+
def belongs_to(name, scope = nil, options = {})
|
1407
|
+
Builder::BelongsTo.build(self, name, scope, options)
|
1432
1408
|
end
|
1433
1409
|
|
1434
1410
|
# Specifies a many-to-many relationship with another class. This associates two classes via an
|
1435
1411
|
# intermediate join table. Unless the join table is explicitly specified as an option, it is
|
1436
1412
|
# guessed using the lexical order of the class names. So a join between Developer and Project
|
1437
|
-
# will give the default join table name of "developers_projects" because "D"
|
1413
|
+
# will give the default join table name of "developers_projects" because "D" precedes "P" alphabetically.
|
1438
1414
|
# Note that this precedence is calculated using the <tt><</tt> operator for String. This
|
1439
1415
|
# means that if the strings are of different lengths, and the strings are equal when compared
|
1440
1416
|
# up to the shortest length, then the longer string is considered of higher
|
@@ -1442,13 +1418,15 @@ module ActiveRecord
|
|
1442
1418
|
# to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes",
|
1443
1419
|
# but it in fact generates a join table name of "paper_boxes_papers". Be aware of this caveat, and use the
|
1444
1420
|
# custom <tt>:join_table</tt> option if you need to.
|
1421
|
+
# If your tables share a common prefix, it will only appear once at the beginning. For example,
|
1422
|
+
# the tables "catalog_categories" and "catalog_products" generate a join table name of "catalog_categories_products".
|
1445
1423
|
#
|
1446
1424
|
# The join table should not have a primary key or a model associated with it. You must manually generate the
|
1447
1425
|
# join table with a migration such as this:
|
1448
1426
|
#
|
1449
1427
|
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration
|
1450
1428
|
# def change
|
1451
|
-
# create_table :developers_projects, :
|
1429
|
+
# create_table :developers_projects, id: false do |t|
|
1452
1430
|
# t.integer :developer_id
|
1453
1431
|
# t.integer :project_id
|
1454
1432
|
# end
|
@@ -1468,10 +1446,13 @@ module ActiveRecord
|
|
1468
1446
|
# Adds one or more objects to the collection by creating associations in the join table
|
1469
1447
|
# (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
|
1470
1448
|
# Note that this operation instantly fires update sql without waiting for the save or update call on the
|
1471
|
-
# parent object.
|
1449
|
+
# parent object, unless the parent object is a new record.
|
1472
1450
|
# [collection.delete(object, ...)]
|
1473
1451
|
# Removes one or more objects from the collection by removing their associations from the join table.
|
1474
1452
|
# This does not destroy the objects.
|
1453
|
+
# [collection.destroy(object, ...)]
|
1454
|
+
# Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option.
|
1455
|
+
# This does not destroy the objects.
|
1475
1456
|
# [collection=objects]
|
1476
1457
|
# Replaces the collection's content by deleting and adding objects as appropriate.
|
1477
1458
|
# [collection_singular_ids]
|
@@ -1508,6 +1489,7 @@ module ActiveRecord
|
|
1508
1489
|
# * <tt>Developer#projects</tt>
|
1509
1490
|
# * <tt>Developer#projects<<</tt>
|
1510
1491
|
# * <tt>Developer#projects.delete</tt>
|
1492
|
+
# * <tt>Developer#projects.destroy</tt>
|
1511
1493
|
# * <tt>Developer#projects=</tt>
|
1512
1494
|
# * <tt>Developer#project_ids</tt>
|
1513
1495
|
# * <tt>Developer#project_ids=</tt>
|
@@ -1540,47 +1522,6 @@ module ActiveRecord
|
|
1540
1522
|
# By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
|
1541
1523
|
# So if a Person class makes a +has_and_belongs_to_many+ association to Project,
|
1542
1524
|
# the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
|
1543
|
-
# [:conditions]
|
1544
|
-
# Specify the conditions that the associated object must meet in order to be included as a +WHERE+
|
1545
|
-
# SQL fragment, such as <tt>authorized = 1</tt>. Record creations from the association are
|
1546
|
-
# scoped if a hash is used.
|
1547
|
-
# <tt>has_many :posts, :conditions => {:published => true}</tt> will create published posts with <tt>@blog.posts.create</tt>
|
1548
|
-
# or <tt>@blog.posts.build</tt>.
|
1549
|
-
# [:order]
|
1550
|
-
# Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment,
|
1551
|
-
# such as <tt>last_name, first_name DESC</tt>
|
1552
|
-
# [:uniq]
|
1553
|
-
# If true, duplicate associated objects will be ignored by accessors and query methods.
|
1554
|
-
# [:finder_sql]
|
1555
|
-
# Overwrite the default generated SQL statement used to fetch the association with a manual statement
|
1556
|
-
# [:counter_sql]
|
1557
|
-
# Specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is
|
1558
|
-
# specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by
|
1559
|
-
# replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>.
|
1560
|
-
# [:delete_sql]
|
1561
|
-
# Overwrite the default generated SQL statement used to remove links between the associated
|
1562
|
-
# classes with a manual statement.
|
1563
|
-
# [:insert_sql]
|
1564
|
-
# Overwrite the default generated SQL statement used to add links between the associated classes
|
1565
|
-
# with a manual statement.
|
1566
|
-
# [:extend]
|
1567
|
-
# Anonymous module for extending the proxy, see "Association extensions".
|
1568
|
-
# [:include]
|
1569
|
-
# Specify second-order associations that should be eager loaded when the collection is loaded.
|
1570
|
-
# [:group]
|
1571
|
-
# An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
|
1572
|
-
# [:having]
|
1573
|
-
# Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt> returns.
|
1574
|
-
# Uses the <tt>HAVING</tt> SQL-clause.
|
1575
|
-
# [:limit]
|
1576
|
-
# An integer determining the limit on the number of rows that should be returned.
|
1577
|
-
# [:offset]
|
1578
|
-
# An integer determining the offset from where the rows should be fetched. So at 5,
|
1579
|
-
# it would skip the first 4 rows.
|
1580
|
-
# [:select]
|
1581
|
-
# By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example,
|
1582
|
-
# you want to do a join but not include the joined columns. Do not forget to include the primary
|
1583
|
-
# and foreign keys, otherwise it will raise an error.
|
1584
1525
|
# [:readonly]
|
1585
1526
|
# If true, all the associated objects are readonly through the association.
|
1586
1527
|
# [:validate]
|
@@ -1591,16 +1532,16 @@ module ActiveRecord
|
|
1591
1532
|
# If false, never save or destroy the associated objects.
|
1592
1533
|
# By default, only save associated objects that are new records.
|
1593
1534
|
#
|
1535
|
+
# Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
|
1536
|
+
#
|
1594
1537
|
# Option examples:
|
1595
1538
|
# has_and_belongs_to_many :projects
|
1596
|
-
# has_and_belongs_to_many :projects,
|
1597
|
-
# has_and_belongs_to_many :nations, :
|
1598
|
-
# has_and_belongs_to_many :categories, :
|
1599
|
-
# has_and_belongs_to_many :categories,
|
1600
|
-
|
1601
|
-
|
1602
|
-
def has_and_belongs_to_many(name, options = {}, &extension)
|
1603
|
-
Builder::HasAndBelongsToMany.build(self, name, options, &extension)
|
1539
|
+
# has_and_belongs_to_many :projects, -> { includes :milestones, :manager }
|
1540
|
+
# has_and_belongs_to_many :nations, class_name: "Country"
|
1541
|
+
# has_and_belongs_to_many :categories, join_table: "prods_cats"
|
1542
|
+
# has_and_belongs_to_many :categories, -> { readonly }
|
1543
|
+
def has_and_belongs_to_many(name, scope = nil, options = {}, &extension)
|
1544
|
+
Builder::HasAndBelongsToMany.build(self, name, scope, options, &extension)
|
1604
1545
|
end
|
1605
1546
|
end
|
1606
1547
|
end
|