rails 4.1.4 → 4.2.11.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +12 -10
- data/guides/CHANGELOG.md +87 -15
- data/guides/Rakefile +21 -6
- data/guides/assets/images/getting_started/article_with_comments.png +0 -0
- data/guides/assets/javascripts/guides.js +6 -0
- data/guides/assets/stylesheets/main.css +4 -1
- data/guides/bug_report_templates/action_controller_gem.rb +3 -3
- data/guides/bug_report_templates/action_controller_master.rb +3 -2
- data/guides/bug_report_templates/active_record_gem.rb +1 -1
- data/guides/bug_report_templates/generic_gem.rb +15 -0
- data/guides/bug_report_templates/generic_master.rb +26 -0
- data/guides/rails_guides/helpers.rb +1 -1
- data/guides/rails_guides/levenshtein.rb +27 -21
- data/guides/rails_guides/markdown/renderer.rb +1 -1
- data/guides/rails_guides/markdown.rb +11 -7
- data/guides/rails_guides.rb +2 -2
- data/guides/source/2_2_release_notes.md +1 -1
- data/guides/source/2_3_release_notes.md +4 -4
- data/guides/source/3_0_release_notes.md +8 -8
- data/guides/source/3_1_release_notes.md +6 -3
- data/guides/source/3_2_release_notes.md +6 -3
- data/guides/source/4_0_release_notes.md +6 -3
- data/guides/source/4_1_release_notes.md +10 -11
- data/guides/source/4_2_release_notes.md +877 -0
- data/guides/source/_license.html.erb +1 -1
- data/guides/source/_welcome.html.erb +6 -8
- data/guides/source/action_controller_overview.md +28 -11
- data/guides/source/action_mailer_basics.md +97 -29
- data/guides/source/action_view_overview.md +142 -191
- data/guides/source/active_job_basics.md +339 -0
- data/guides/source/active_model_basics.md +371 -17
- data/guides/source/active_record_basics.md +25 -24
- data/guides/source/active_record_callbacks.md +12 -9
- data/guides/source/{migrations.md → active_record_migrations.md} +135 -226
- data/guides/source/active_record_postgresql.md +433 -0
- data/guides/source/active_record_querying.md +270 -262
- data/guides/source/active_record_validations.md +24 -14
- data/guides/source/active_support_core_extensions.md +115 -123
- data/guides/source/active_support_instrumentation.md +10 -18
- data/guides/source/api_documentation_guidelines.md +63 -17
- data/guides/source/asset_pipeline.md +266 -125
- data/guides/source/association_basics.md +96 -80
- data/guides/source/autoloading_and_reloading_constants.md +1311 -0
- data/guides/source/caching_with_rails.md +32 -7
- data/guides/source/command_line.md +52 -30
- data/guides/source/configuring.md +161 -33
- data/guides/source/contributing_to_ruby_on_rails.md +198 -114
- data/guides/source/credits.html.erb +2 -2
- data/guides/source/debugging_rails_applications.md +448 -294
- data/guides/source/development_dependencies_install.md +47 -36
- data/guides/source/documents.yaml +19 -7
- data/guides/source/engines.md +217 -196
- data/guides/source/form_helpers.md +79 -56
- data/guides/source/generators.md +24 -11
- data/guides/source/getting_started.md +361 -222
- data/guides/source/i18n.md +113 -69
- data/guides/source/index.html.erb +1 -0
- data/guides/source/initialization.md +110 -63
- data/guides/source/layout.html.erb +5 -11
- data/guides/source/layouts_and_rendering.md +26 -26
- data/guides/source/maintenance_policy.md +26 -4
- data/guides/source/nested_model_forms.md +7 -4
- data/guides/source/plugins.md +27 -27
- data/guides/source/rails_application_templates.md +21 -3
- data/guides/source/rails_on_rack.md +12 -10
- data/guides/source/routing.md +115 -75
- data/guides/source/ruby_on_rails_guides_guidelines.md +11 -12
- data/guides/source/security.md +41 -35
- data/guides/source/testing.md +199 -119
- data/guides/source/upgrading_ruby_on_rails.md +319 -32
- data/guides/source/working_with_javascript_in_rails.md +19 -17
- data/guides/w3c_validator.rb +2 -0
- metadata +42 -95
- data/guides/code/getting_started/Gemfile +0 -40
- data/guides/code/getting_started/Gemfile.lock +0 -125
- data/guides/code/getting_started/README.rdoc +0 -28
- data/guides/code/getting_started/Rakefile +0 -6
- data/guides/code/getting_started/app/assets/javascripts/application.js +0 -15
- data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
- data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
- data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
- data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -23
- data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -53
- data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
- data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
- data/guides/code/getting_started/app/models/comment.rb +0 -3
- data/guides/code/getting_started/app/models/post.rb +0 -7
- data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
- data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
- data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
- data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
- data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
- data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
- data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -4
- data/guides/code/getting_started/bin/bundle +0 -4
- data/guides/code/getting_started/bin/rails +0 -4
- data/guides/code/getting_started/bin/rake +0 -4
- data/guides/code/getting_started/config/application.rb +0 -18
- data/guides/code/getting_started/config/boot.rb +0 -4
- data/guides/code/getting_started/config/database.yml +0 -25
- data/guides/code/getting_started/config/environment.rb +0 -5
- data/guides/code/getting_started/config/environments/development.rb +0 -30
- data/guides/code/getting_started/config/environments/production.rb +0 -80
- data/guides/code/getting_started/config/environments/test.rb +0 -36
- data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
- data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
- data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
- data/guides/code/getting_started/config/initializers/locale.rb +0 -9
- data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
- data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
- data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
- data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
- data/guides/code/getting_started/config/locales/en.yml +0 -23
- data/guides/code/getting_started/config/routes.rb +0 -7
- data/guides/code/getting_started/config.ru +0 -4
- data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
- data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
- data/guides/code/getting_started/db/schema.rb +0 -33
- data/guides/code/getting_started/db/seeds.rb +0 -7
- data/guides/code/getting_started/public/404.html +0 -60
- data/guides/code/getting_started/public/422.html +0 -60
- data/guides/code/getting_started/public/500.html +0 -59
- data/guides/code/getting_started/public/favicon.ico +0 -0
- data/guides/code/getting_started/public/robots.txt +0 -5
- data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
- data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
- data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
- data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
- data/guides/code/getting_started/test/models/comment_test.rb +0 -7
- data/guides/code/getting_started/test/models/post_test.rb +0 -7
- data/guides/code/getting_started/test/test_helper.rb +0 -12
@@ -101,13 +101,13 @@ class CreateOrders < ActiveRecord::Migration
|
|
101
101
|
def change
|
102
102
|
create_table :customers do |t|
|
103
103
|
t.string :name
|
104
|
-
t.timestamps
|
104
|
+
t.timestamps null: false
|
105
105
|
end
|
106
106
|
|
107
107
|
create_table :orders do |t|
|
108
|
-
t.belongs_to :customer
|
108
|
+
t.belongs_to :customer, index: true
|
109
109
|
t.datetime :order_date
|
110
|
-
t.timestamps
|
110
|
+
t.timestamps null: false
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
@@ -132,13 +132,13 @@ class CreateSuppliers < ActiveRecord::Migration
|
|
132
132
|
def change
|
133
133
|
create_table :suppliers do |t|
|
134
134
|
t.string :name
|
135
|
-
t.timestamps
|
135
|
+
t.timestamps null: false
|
136
136
|
end
|
137
137
|
|
138
138
|
create_table :accounts do |t|
|
139
|
-
t.belongs_to :supplier
|
139
|
+
t.belongs_to :supplier, index: true
|
140
140
|
t.string :account_number
|
141
|
-
t.timestamps
|
141
|
+
t.timestamps null: false
|
142
142
|
end
|
143
143
|
end
|
144
144
|
end
|
@@ -165,13 +165,13 @@ class CreateCustomers < ActiveRecord::Migration
|
|
165
165
|
def change
|
166
166
|
create_table :customers do |t|
|
167
167
|
t.string :name
|
168
|
-
t.timestamps
|
168
|
+
t.timestamps null: false
|
169
169
|
end
|
170
170
|
|
171
171
|
create_table :orders do |t|
|
172
|
-
t.belongs_to :customer
|
172
|
+
t.belongs_to :customer, index: true
|
173
173
|
t.datetime :order_date
|
174
|
-
t.timestamps
|
174
|
+
t.timestamps null: false
|
175
175
|
end
|
176
176
|
end
|
177
177
|
end
|
@@ -207,19 +207,19 @@ class CreateAppointments < ActiveRecord::Migration
|
|
207
207
|
def change
|
208
208
|
create_table :physicians do |t|
|
209
209
|
t.string :name
|
210
|
-
t.timestamps
|
210
|
+
t.timestamps null: false
|
211
211
|
end
|
212
212
|
|
213
213
|
create_table :patients do |t|
|
214
214
|
t.string :name
|
215
|
-
t.timestamps
|
215
|
+
t.timestamps null: false
|
216
216
|
end
|
217
217
|
|
218
218
|
create_table :appointments do |t|
|
219
|
-
t.belongs_to :physician
|
220
|
-
t.belongs_to :patient
|
219
|
+
t.belongs_to :physician, index: true
|
220
|
+
t.belongs_to :patient, index: true
|
221
221
|
t.datetime :appointment_date
|
222
|
-
t.timestamps
|
222
|
+
t.timestamps null: false
|
223
223
|
end
|
224
224
|
end
|
225
225
|
end
|
@@ -291,19 +291,19 @@ class CreateAccountHistories < ActiveRecord::Migration
|
|
291
291
|
def change
|
292
292
|
create_table :suppliers do |t|
|
293
293
|
t.string :name
|
294
|
-
t.timestamps
|
294
|
+
t.timestamps null: false
|
295
295
|
end
|
296
296
|
|
297
297
|
create_table :accounts do |t|
|
298
|
-
t.belongs_to :supplier
|
298
|
+
t.belongs_to :supplier, index: true
|
299
299
|
t.string :account_number
|
300
|
-
t.timestamps
|
300
|
+
t.timestamps null: false
|
301
301
|
end
|
302
302
|
|
303
303
|
create_table :account_histories do |t|
|
304
|
-
t.belongs_to :account
|
304
|
+
t.belongs_to :account, index: true
|
305
305
|
t.integer :credit_rating
|
306
|
-
t.timestamps
|
306
|
+
t.timestamps null: false
|
307
307
|
end
|
308
308
|
end
|
309
309
|
end
|
@@ -332,17 +332,17 @@ class CreateAssembliesAndParts < ActiveRecord::Migration
|
|
332
332
|
def change
|
333
333
|
create_table :assemblies do |t|
|
334
334
|
t.string :name
|
335
|
-
t.timestamps
|
335
|
+
t.timestamps null: false
|
336
336
|
end
|
337
337
|
|
338
338
|
create_table :parts do |t|
|
339
339
|
t.string :part_number
|
340
|
-
t.timestamps
|
340
|
+
t.timestamps null: false
|
341
341
|
end
|
342
342
|
|
343
343
|
create_table :assemblies_parts, id: false do |t|
|
344
|
-
t.belongs_to :assembly
|
345
|
-
t.belongs_to :part
|
344
|
+
t.belongs_to :assembly, index: true
|
345
|
+
t.belongs_to :part, index: true
|
346
346
|
end
|
347
347
|
end
|
348
348
|
end
|
@@ -371,14 +371,16 @@ class CreateSuppliers < ActiveRecord::Migration
|
|
371
371
|
def change
|
372
372
|
create_table :suppliers do |t|
|
373
373
|
t.string :name
|
374
|
-
t.timestamps
|
374
|
+
t.timestamps null: false
|
375
375
|
end
|
376
376
|
|
377
377
|
create_table :accounts do |t|
|
378
378
|
t.integer :supplier_id
|
379
379
|
t.string :account_number
|
380
|
-
t.timestamps
|
380
|
+
t.timestamps null: false
|
381
381
|
end
|
382
|
+
|
383
|
+
add_index :accounts, :supplier_id
|
382
384
|
end
|
383
385
|
end
|
384
386
|
```
|
@@ -453,8 +455,10 @@ class CreatePictures < ActiveRecord::Migration
|
|
453
455
|
t.string :name
|
454
456
|
t.integer :imageable_id
|
455
457
|
t.string :imageable_type
|
456
|
-
t.timestamps
|
458
|
+
t.timestamps null: false
|
457
459
|
end
|
460
|
+
|
461
|
+
add_index :pictures, :imageable_id
|
458
462
|
end
|
459
463
|
end
|
460
464
|
```
|
@@ -466,8 +470,8 @@ class CreatePictures < ActiveRecord::Migration
|
|
466
470
|
def change
|
467
471
|
create_table :pictures do |t|
|
468
472
|
t.string :name
|
469
|
-
t.references :imageable, polymorphic: true
|
470
|
-
t.timestamps
|
473
|
+
t.references :imageable, polymorphic: true, index: true
|
474
|
+
t.timestamps null: false
|
471
475
|
end
|
472
476
|
end
|
473
477
|
end
|
@@ -496,8 +500,8 @@ In your migrations/schema, you will add a references column to the model itself.
|
|
496
500
|
class CreateEmployees < ActiveRecord::Migration
|
497
501
|
def change
|
498
502
|
create_table :employees do |t|
|
499
|
-
t.references :manager
|
500
|
-
t.timestamps
|
503
|
+
t.references :manager, index: true
|
504
|
+
t.timestamps null: false
|
501
505
|
end
|
502
506
|
end
|
503
507
|
end
|
@@ -561,6 +565,8 @@ class CreateOrders < ActiveRecord::Migration
|
|
561
565
|
t.string :order_number
|
562
566
|
t.integer :customer_id
|
563
567
|
end
|
568
|
+
|
569
|
+
add_index :orders, :customer_id
|
564
570
|
end
|
565
571
|
end
|
566
572
|
```
|
@@ -571,7 +577,7 @@ If you create an association some time after you build the underlying model, you
|
|
571
577
|
|
572
578
|
If you create a `has_and_belongs_to_many` association, you need to explicitly create the joining table. Unless the name of the join table is explicitly specified by using the `:join_table` option, Active Record creates the name by using the lexical order of the class names. So a join between customer and order models will give the default join table name of "customers_orders" because "c" outranks "o" in lexical ordering.
|
573
579
|
|
574
|
-
WARNING: The precedence between model names is calculated using the `<` operator for `String`. This means that if the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered of higher lexical precedence than the shorter one. For example, one would expect the tables "
|
580
|
+
WARNING: The precedence between model names is calculated using the `<` operator for `String`. This means that if the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered of higher lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers" to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", but it in fact generates a join table name of "paper_boxes_papers" (because the underscore '_' is lexicographically _less_ than 's' in common encodings).
|
575
581
|
|
576
582
|
Whatever the name, you must manually generate the join table with an appropriate migration. For example, consider these associations:
|
577
583
|
|
@@ -594,6 +600,9 @@ class CreateAssembliesPartsJoinTable < ActiveRecord::Migration
|
|
594
600
|
t.integer :assembly_id
|
595
601
|
t.integer :part_id
|
596
602
|
end
|
603
|
+
|
604
|
+
add_index :assemblies_parts, :assembly_id
|
605
|
+
add_index :assemblies_parts, :part_id
|
597
606
|
end
|
598
607
|
end
|
599
608
|
```
|
@@ -747,7 +756,7 @@ class Order < ActiveRecord::Base
|
|
747
756
|
end
|
748
757
|
```
|
749
758
|
|
750
|
-
Each instance of the
|
759
|
+
Each instance of the `Order` model will have these methods:
|
751
760
|
|
752
761
|
```ruby
|
753
762
|
customer
|
@@ -1131,7 +1140,7 @@ The `has_one` association supports these options:
|
|
1131
1140
|
|
1132
1141
|
##### `:as`
|
1133
1142
|
|
1134
|
-
Setting the `:as` option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail
|
1143
|
+
Setting the `:as` option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail [earlier in this guide](#polymorphic-associations).
|
1135
1144
|
|
1136
1145
|
##### `:autosave`
|
1137
1146
|
|
@@ -1203,7 +1212,7 @@ The `:source_type` option specifies the source association type for a `has_one :
|
|
1203
1212
|
|
1204
1213
|
##### `:through`
|
1205
1214
|
|
1206
|
-
The `:through` option specifies a join model through which to perform the query. `has_one :through` associations were discussed in detail
|
1215
|
+
The `:through` option specifies a join model through which to perform the query. `has_one :through` associations were discussed in detail [earlier in this guide](#the-has-one-through-association).
|
1207
1216
|
|
1208
1217
|
##### `:validate`
|
1209
1218
|
|
@@ -1312,9 +1321,9 @@ When you declare a `has_many` association, the declaring class automatically gai
|
|
1312
1321
|
* `collection<<(object, ...)`
|
1313
1322
|
* `collection.delete(object, ...)`
|
1314
1323
|
* `collection.destroy(object, ...)`
|
1315
|
-
* `collection=objects`
|
1324
|
+
* `collection=(objects)`
|
1316
1325
|
* `collection_singular_ids`
|
1317
|
-
* `collection_singular_ids=ids`
|
1326
|
+
* `collection_singular_ids=(ids)`
|
1318
1327
|
* `collection.clear`
|
1319
1328
|
* `collection.empty?`
|
1320
1329
|
* `collection.size`
|
@@ -1333,16 +1342,16 @@ class Customer < ActiveRecord::Base
|
|
1333
1342
|
end
|
1334
1343
|
```
|
1335
1344
|
|
1336
|
-
Each instance of the
|
1345
|
+
Each instance of the `Customer` model will have these methods:
|
1337
1346
|
|
1338
1347
|
```ruby
|
1339
1348
|
orders(force_reload = false)
|
1340
1349
|
orders<<(object, ...)
|
1341
1350
|
orders.delete(object, ...)
|
1342
1351
|
orders.destroy(object, ...)
|
1343
|
-
orders=objects
|
1352
|
+
orders=(objects)
|
1344
1353
|
order_ids
|
1345
|
-
order_ids=ids
|
1354
|
+
order_ids=(ids)
|
1346
1355
|
orders.clear
|
1347
1356
|
orders.empty?
|
1348
1357
|
orders.size
|
@@ -1390,7 +1399,7 @@ The `collection.destroy` method removes one or more objects from the collection
|
|
1390
1399
|
|
1391
1400
|
WARNING: Objects will _always_ be removed from the database, ignoring the `:dependent` option.
|
1392
1401
|
|
1393
|
-
##### `collection=objects`
|
1402
|
+
##### `collection=(objects)`
|
1394
1403
|
|
1395
1404
|
The `collection=` method makes the collection contain only the supplied objects, by adding and deleting as appropriate.
|
1396
1405
|
|
@@ -1402,13 +1411,19 @@ The `collection_singular_ids` method returns an array of the ids of the objects
|
|
1402
1411
|
@order_ids = @customer.order_ids
|
1403
1412
|
```
|
1404
1413
|
|
1405
|
-
##### `collection_singular_ids=ids`
|
1414
|
+
##### `collection_singular_ids=(ids)`
|
1406
1415
|
|
1407
1416
|
The `collection_singular_ids=` method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate.
|
1408
1417
|
|
1409
1418
|
##### `collection.clear`
|
1410
1419
|
|
1411
|
-
The `collection.clear` method removes
|
1420
|
+
The `collection.clear` method removes all objects from the collection according to the strategy specified by the `dependent` option. If no option is given, it follows the default strategy. The default strategy for `has_many :through` associations is `delete_all`, and for `has_many` associations is to set the foreign keys to `NULL`.
|
1421
|
+
|
1422
|
+
```ruby
|
1423
|
+
@customer.orders.clear
|
1424
|
+
```
|
1425
|
+
|
1426
|
+
WARNING: Objects will be delete if they're associated with `dependent: :destroy`, just like `dependent: :delete_all`.
|
1412
1427
|
|
1413
1428
|
##### `collection.empty?`
|
1414
1429
|
|
@@ -1447,7 +1462,9 @@ The `collection.where` method finds objects within the collection based on the c
|
|
1447
1462
|
|
1448
1463
|
##### `collection.exists?(...)`
|
1449
1464
|
|
1450
|
-
The `collection.exists?` method checks whether an object meeting the supplied
|
1465
|
+
The `collection.exists?` method checks whether an object meeting the supplied
|
1466
|
+
conditions exists in the collection. It uses the same syntax and options as
|
1467
|
+
[`ActiveRecord::Base.exists?`](http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F).
|
1451
1468
|
|
1452
1469
|
##### `collection.build(attributes = {}, ...)`
|
1453
1470
|
|
@@ -1497,7 +1514,7 @@ The `has_many` association supports these options:
|
|
1497
1514
|
|
1498
1515
|
##### `:as`
|
1499
1516
|
|
1500
|
-
Setting the `:as` option indicates that this is a polymorphic association, as discussed
|
1517
|
+
Setting the `:as` option indicates that this is a polymorphic association, as discussed [earlier in this guide](#polymorphic-associations).
|
1501
1518
|
|
1502
1519
|
##### `:autosave`
|
1503
1520
|
|
@@ -1523,8 +1540,6 @@ Controls what happens to the associated objects when their owner is destroyed:
|
|
1523
1540
|
* `:restrict_with_exception` causes an exception to be raised if there are any associated records
|
1524
1541
|
* `:restrict_with_error` causes an error to be added to the owner if there are any associated objects
|
1525
1542
|
|
1526
|
-
NOTE: This option is ignored when you use the `:through` option on the association.
|
1527
|
-
|
1528
1543
|
##### `:foreign_key`
|
1529
1544
|
|
1530
1545
|
By convention, Rails assumes that the column used to hold the foreign key on the other model is the name of this model with the suffix `_id` added. The `:foreign_key` option lets you set the name of the foreign key directly:
|
@@ -1579,7 +1594,7 @@ The `:source_type` option specifies the source association type for a `has_many
|
|
1579
1594
|
|
1580
1595
|
##### `:through`
|
1581
1596
|
|
1582
|
-
The `:through` option specifies a join model through which to perform the query. `has_many :through` associations provide a way to implement many-to-many relationships, as discussed
|
1597
|
+
The `:through` option specifies a join model through which to perform the query. `has_many :through` associations provide a way to implement many-to-many relationships, as discussed [earlier in this guide](#the-has-many-through-association).
|
1583
1598
|
|
1584
1599
|
##### `:validate`
|
1585
1600
|
|
@@ -1632,7 +1647,7 @@ If you use a hash-style `where` option, then record creation via this associatio
|
|
1632
1647
|
|
1633
1648
|
##### `extending`
|
1634
1649
|
|
1635
|
-
The `extending` method specifies a named module to extend the association proxy. Association extensions are discussed in detail
|
1650
|
+
The `extending` method specifies a named module to extend the association proxy. Association extensions are discussed in detail [later in this guide](#association-extensions).
|
1636
1651
|
|
1637
1652
|
##### `group`
|
1638
1653
|
|
@@ -1725,58 +1740,58 @@ mostly useful together with the `:through` option.
|
|
1725
1740
|
```ruby
|
1726
1741
|
class Person < ActiveRecord::Base
|
1727
1742
|
has_many :readings
|
1728
|
-
has_many :
|
1743
|
+
has_many :articles, through: :readings
|
1729
1744
|
end
|
1730
1745
|
|
1731
1746
|
person = Person.create(name: 'John')
|
1732
|
-
|
1733
|
-
person.
|
1734
|
-
person.
|
1735
|
-
person.
|
1736
|
-
Reading.all.inspect # => [#<Reading id: 12, person_id: 5,
|
1747
|
+
article = Article.create(name: 'a1')
|
1748
|
+
person.articles << article
|
1749
|
+
person.articles << article
|
1750
|
+
person.articles.inspect # => [#<Article id: 5, name: "a1">, #<Article id: 5, name: "a1">]
|
1751
|
+
Reading.all.inspect # => [#<Reading id: 12, person_id: 5, article_id: 5>, #<Reading id: 13, person_id: 5, article_id: 5>]
|
1737
1752
|
```
|
1738
1753
|
|
1739
|
-
In the above case there are two readings and `person.
|
1740
|
-
them even though these records are pointing to the same
|
1754
|
+
In the above case there are two readings and `person.articles` brings out both of
|
1755
|
+
them even though these records are pointing to the same article.
|
1741
1756
|
|
1742
1757
|
Now let's set `distinct`:
|
1743
1758
|
|
1744
1759
|
```ruby
|
1745
1760
|
class Person
|
1746
1761
|
has_many :readings
|
1747
|
-
has_many :
|
1762
|
+
has_many :articles, -> { distinct }, through: :readings
|
1748
1763
|
end
|
1749
1764
|
|
1750
1765
|
person = Person.create(name: 'Honda')
|
1751
|
-
|
1752
|
-
person.
|
1753
|
-
person.
|
1754
|
-
person.
|
1755
|
-
Reading.all.inspect # => [#<Reading id: 16, person_id: 7,
|
1766
|
+
article = Article.create(name: 'a1')
|
1767
|
+
person.articles << article
|
1768
|
+
person.articles << article
|
1769
|
+
person.articles.inspect # => [#<Article id: 7, name: "a1">]
|
1770
|
+
Reading.all.inspect # => [#<Reading id: 16, person_id: 7, article_id: 7>, #<Reading id: 17, person_id: 7, article_id: 7>]
|
1756
1771
|
```
|
1757
1772
|
|
1758
|
-
In the above case there are still two readings. However `person.
|
1759
|
-
only one
|
1773
|
+
In the above case there are still two readings. However `person.articles` shows
|
1774
|
+
only one article because the collection loads only unique records.
|
1760
1775
|
|
1761
1776
|
If you want to make sure that, upon insertion, all of the records in the
|
1762
1777
|
persisted association are distinct (so that you can be sure that when you
|
1763
1778
|
inspect the association that you will never find duplicate records), you should
|
1764
1779
|
add a unique index on the table itself. For example, if you have a table named
|
1765
|
-
`
|
1780
|
+
`person_articles` and you want to make sure all the articles are unique, you could
|
1766
1781
|
add the following in a migration:
|
1767
1782
|
|
1768
1783
|
```ruby
|
1769
|
-
add_index :
|
1784
|
+
add_index :person_articles, :article, unique: true
|
1770
1785
|
```
|
1771
1786
|
|
1772
1787
|
Note that checking for uniqueness using something like `include?` is subject
|
1773
1788
|
to race conditions. Do not attempt to use `include?` to enforce distinctness
|
1774
|
-
in an association. For instance, using the
|
1789
|
+
in an association. For instance, using the article example from above, the
|
1775
1790
|
following code would be racy because multiple users could be attempting this
|
1776
1791
|
at the same time:
|
1777
1792
|
|
1778
1793
|
```ruby
|
1779
|
-
person.
|
1794
|
+
person.articles << article unless person.articles.include?(article)
|
1780
1795
|
```
|
1781
1796
|
|
1782
1797
|
#### When are Objects Saved?
|
@@ -1801,9 +1816,9 @@ When you declare a `has_and_belongs_to_many` association, the declaring class au
|
|
1801
1816
|
* `collection<<(object, ...)`
|
1802
1817
|
* `collection.delete(object, ...)`
|
1803
1818
|
* `collection.destroy(object, ...)`
|
1804
|
-
* `collection=objects`
|
1819
|
+
* `collection=(objects)`
|
1805
1820
|
* `collection_singular_ids`
|
1806
|
-
* `collection_singular_ids=ids`
|
1821
|
+
* `collection_singular_ids=(ids)`
|
1807
1822
|
* `collection.clear`
|
1808
1823
|
* `collection.empty?`
|
1809
1824
|
* `collection.size`
|
@@ -1822,16 +1837,16 @@ class Part < ActiveRecord::Base
|
|
1822
1837
|
end
|
1823
1838
|
```
|
1824
1839
|
|
1825
|
-
Each instance of the
|
1840
|
+
Each instance of the `Part` model will have these methods:
|
1826
1841
|
|
1827
1842
|
```ruby
|
1828
1843
|
assemblies(force_reload = false)
|
1829
1844
|
assemblies<<(object, ...)
|
1830
1845
|
assemblies.delete(object, ...)
|
1831
1846
|
assemblies.destroy(object, ...)
|
1832
|
-
assemblies=objects
|
1847
|
+
assemblies=(objects)
|
1833
1848
|
assembly_ids
|
1834
|
-
assembly_ids=ids
|
1849
|
+
assembly_ids=(ids)
|
1835
1850
|
assemblies.clear
|
1836
1851
|
assemblies.empty?
|
1837
1852
|
assemblies.size
|
@@ -1886,7 +1901,7 @@ The `collection.destroy` method removes one or more objects from the collection
|
|
1886
1901
|
@part.assemblies.destroy(@assembly1)
|
1887
1902
|
```
|
1888
1903
|
|
1889
|
-
##### `collection=objects`
|
1904
|
+
##### `collection=(objects)`
|
1890
1905
|
|
1891
1906
|
The `collection=` method makes the collection contain only the supplied objects, by adding and deleting as appropriate.
|
1892
1907
|
|
@@ -1898,7 +1913,7 @@ The `collection_singular_ids` method returns an array of the ids of the objects
|
|
1898
1913
|
@assembly_ids = @part.assembly_ids
|
1899
1914
|
```
|
1900
1915
|
|
1901
|
-
##### `collection_singular_ids=ids`
|
1916
|
+
##### `collection_singular_ids=(ids)`
|
1902
1917
|
|
1903
1918
|
The `collection_singular_ids=` method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate.
|
1904
1919
|
|
@@ -1942,7 +1957,9 @@ The `collection.where` method finds objects within the collection based on the c
|
|
1942
1957
|
|
1943
1958
|
##### `collection.exists?(...)`
|
1944
1959
|
|
1945
|
-
The `collection.exists?` method checks whether an object meeting the supplied
|
1960
|
+
The `collection.exists?` method checks whether an object meeting the supplied
|
1961
|
+
conditions exists in the collection. It uses the same syntax and options as
|
1962
|
+
[`ActiveRecord::Base.exists?`](http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F).
|
1946
1963
|
|
1947
1964
|
##### `collection.build(attributes = {})`
|
1948
1965
|
|
@@ -1970,8 +1987,8 @@ While Rails uses intelligent defaults that will work well in most situations, th
|
|
1970
1987
|
|
1971
1988
|
```ruby
|
1972
1989
|
class Parts < ActiveRecord::Base
|
1973
|
-
has_and_belongs_to_many :assemblies,
|
1974
|
-
|
1990
|
+
has_and_belongs_to_many :assemblies, -> { readonly },
|
1991
|
+
autosave: true
|
1975
1992
|
end
|
1976
1993
|
```
|
1977
1994
|
|
@@ -1983,7 +2000,6 @@ The `has_and_belongs_to_many` association supports these options:
|
|
1983
2000
|
* `:foreign_key`
|
1984
2001
|
* `:join_table`
|
1985
2002
|
* `:validate`
|
1986
|
-
* `:readonly`
|
1987
2003
|
|
1988
2004
|
##### `:association_foreign_key`
|
1989
2005
|
|
@@ -2082,7 +2098,7 @@ If you use a hash-style `where`, then record creation via this association will
|
|
2082
2098
|
|
2083
2099
|
##### `extending`
|
2084
2100
|
|
2085
|
-
The `extending` method specifies a named module to extend the association proxy. Association extensions are discussed in detail
|
2101
|
+
The `extending` method specifies a named module to extend the association proxy. Association extensions are discussed in detail [later in this guide](#association-extensions).
|
2086
2102
|
|
2087
2103
|
##### `group`
|
2088
2104
|
|