rails 4.0.13 → 4.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +20 -15
- data/guides/CHANGELOG.md +5 -74
- data/guides/assets/images/edge_badge.png +0 -0
- data/guides/assets/images/feature_tile.gif +0 -0
- data/guides/assets/images/footer_tile.gif +0 -0
- data/guides/assets/images/fxn.png +0 -0
- data/guides/assets/images/getting_started/challenge.png +0 -0
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_post.png +0 -0
- data/guides/assets/images/getting_started/new_post.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_posts_new.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_posts.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_posts.png +0 -0
- data/guides/assets/images/header_tile.gif +0 -0
- data/guides/assets/images/icons/README +1 -1
- data/guides/assets/images/icons/callouts/11.png +0 -0
- data/guides/assets/images/icons/callouts/12.png +0 -0
- data/guides/assets/images/icons/callouts/13.png +0 -0
- data/guides/assets/images/icons/callouts/15.png +0 -0
- data/guides/assets/images/icons/caution.png +0 -0
- data/guides/assets/images/icons/example.png +0 -0
- data/guides/assets/images/radar.png +0 -0
- data/guides/assets/images/rails4_features.png +0 -0
- data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
- data/guides/assets/images/vijaydev.jpg +0 -0
- data/guides/assets/javascripts/guides.js +30 -34
- data/guides/assets/stylesheets/main.css +2 -1
- data/guides/assets/stylesheets/print.css +1 -1
- data/guides/bug_report_templates/action_controller_gem.rb +2 -0
- data/guides/bug_report_templates/action_controller_master.rb +2 -0
- data/guides/bug_report_templates/active_record_gem.rb +1 -1
- data/guides/bug_report_templates/active_record_master.rb +2 -1
- data/guides/code/getting_started/Gemfile +1 -1
- data/guides/code/getting_started/app/assets/javascripts/application.js +1 -2
- data/guides/code/getting_started/config/environments/development.rb +1 -1
- data/guides/code/getting_started/public/404.html +2 -0
- data/guides/code/getting_started/public/422.html +2 -0
- data/guides/code/getting_started/public/500.html +2 -0
- data/guides/rails_guides/helpers.rb +1 -1
- data/guides/source/2_2_release_notes.md +2 -2
- data/guides/source/2_3_release_notes.md +8 -8
- data/guides/source/3_0_release_notes.md +1 -2
- data/guides/source/3_1_release_notes.md +1 -1
- data/guides/source/3_2_release_notes.md +12 -12
- data/guides/source/4_0_release_notes.md +79 -46
- data/guides/source/4_1_release_notes.md +601 -0
- data/guides/source/_welcome.html.erb +1 -1
- data/guides/source/action_controller_overview.md +117 -31
- data/guides/source/action_mailer_basics.md +19 -19
- data/guides/source/action_view_overview.md +131 -12
- data/guides/source/active_model_basics.md +6 -6
- data/guides/source/active_record_basics.md +15 -15
- data/guides/source/active_record_callbacks.md +18 -16
- data/guides/source/active_record_querying.md +67 -39
- data/guides/source/active_record_validations.md +31 -31
- data/guides/source/active_support_core_extensions.md +63 -74
- data/guides/source/active_support_instrumentation.md +13 -4
- data/guides/source/api_documentation_guidelines.md +19 -5
- data/guides/source/asset_pipeline.md +544 -249
- data/guides/source/association_basics.md +81 -22
- data/guides/source/caching_with_rails.md +15 -6
- data/guides/source/command_line.md +28 -19
- data/guides/source/configuring.md +98 -50
- data/guides/source/contributing_to_ruby_on_rails.md +11 -11
- data/guides/source/credits.html.erb +2 -2
- data/guides/source/debugging_rails_applications.md +36 -5
- data/guides/source/development_dependencies_install.md +89 -8
- data/guides/source/documents.yaml +7 -1
- data/guides/source/engines.md +648 -224
- data/guides/source/form_helpers.md +56 -45
- data/guides/source/generators.md +7 -3
- data/guides/source/getting_started.md +379 -164
- data/guides/source/i18n.md +59 -23
- data/guides/source/index.html.erb +1 -1
- data/guides/source/initialization.md +153 -56
- data/guides/source/kindle/toc.html.erb +1 -1
- data/guides/source/layout.html.erb +3 -3
- data/guides/source/layouts_and_rendering.md +12 -11
- data/guides/source/maintenance_policy.md +4 -23
- data/guides/source/migrations.md +41 -37
- data/guides/source/nested_model_forms.md +3 -3
- data/guides/source/plugins.md +27 -23
- data/guides/source/rails_application_templates.md +25 -6
- data/guides/source/rails_on_rack.md +35 -51
- data/guides/source/routing.md +108 -99
- data/guides/source/ruby_on_rails_guides_guidelines.md +2 -2
- data/guides/source/security.md +33 -31
- data/guides/source/testing.md +37 -34
- data/guides/source/upgrading_ruby_on_rails.md +335 -16
- data/guides/source/working_with_javascript_in_rails.md +18 -10
- metadata +66 -39
- data/guides/assets/images/jaimeiniesta.jpg +0 -0
- data/guides/source/kindle/KINDLE.md +0 -26
@@ -14,7 +14,7 @@ Active Model is a library containing various modules used in developing framewor
|
|
14
14
|
|
15
15
|
### AttributeMethods
|
16
16
|
|
17
|
-
The AttributeMethods module can add custom prefixes and suffixes on methods of a class. It is used by defining the prefixes and suffixes
|
17
|
+
The AttributeMethods module can add custom prefixes and suffixes on methods of a class. It is used by defining the prefixes and suffixes and which methods on the object will use them.
|
18
18
|
|
19
19
|
```ruby
|
20
20
|
class Person
|
@@ -45,7 +45,7 @@ person.age_highest? # false
|
|
45
45
|
|
46
46
|
### Callbacks
|
47
47
|
|
48
|
-
Callbacks gives Active Record style callbacks. This provides
|
48
|
+
Callbacks gives Active Record style callbacks. This provides an ability to define callbacks which run at appropriate times. After defining callbacks, you can wrap them with before, after and around custom methods.
|
49
49
|
|
50
50
|
```ruby
|
51
51
|
class Person
|
@@ -57,19 +57,19 @@ class Person
|
|
57
57
|
|
58
58
|
def update
|
59
59
|
run_callbacks(:update) do
|
60
|
-
# This
|
60
|
+
# This method is called when update is called on an object.
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
64
|
def reset_me
|
65
|
-
# This method
|
65
|
+
# This method is called when update is called on an object as a before_update callback is defined.
|
66
66
|
end
|
67
67
|
end
|
68
68
|
```
|
69
69
|
|
70
70
|
### Conversion
|
71
71
|
|
72
|
-
If a class defines `persisted?` and `id` methods then you can include `Conversion` module in that class and
|
72
|
+
If a class defines `persisted?` and `id` methods, then you can include the `Conversion` module in that class and call the Rails conversion methods on objects of that class.
|
73
73
|
|
74
74
|
```ruby
|
75
75
|
class Person
|
@@ -120,8 +120,8 @@ class Person
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def save
|
123
|
-
@previously_changed = changes
|
124
123
|
# do save work...
|
124
|
+
changes_applied
|
125
125
|
end
|
126
126
|
end
|
127
127
|
```
|
@@ -48,10 +48,10 @@ overall database access code.
|
|
48
48
|
Active Record gives us several mechanisms, the most important being the ability
|
49
49
|
to:
|
50
50
|
|
51
|
-
* Represent models and their data
|
52
|
-
* Represent associations between these models
|
53
|
-
* Represent inheritance hierarchies through related models
|
54
|
-
* Validate models before they get persisted to the database
|
51
|
+
* Represent models and their data.
|
52
|
+
* Represent associations between these models.
|
53
|
+
* Represent inheritance hierarchies through related models.
|
54
|
+
* Validate models before they get persisted to the database.
|
55
55
|
* Perform database operations in an object-oriented fashion.
|
56
56
|
|
57
57
|
Convention over Configuration in Active Record
|
@@ -62,9 +62,9 @@ may be necessary to write a lot of configuration code. This is particularly true
|
|
62
62
|
for ORM frameworks in general. However, if you follow the conventions adopted by
|
63
63
|
Rails, you'll need to write very little configuration (in some case no
|
64
64
|
configuration at all) when creating Active Record models. The idea is that if
|
65
|
-
you configure your applications in the very same way most of the
|
66
|
-
should be the default way.
|
67
|
-
only in those cases where you can't follow the
|
65
|
+
you configure your applications in the very same way most of the time then this
|
66
|
+
should be the default way. Thus, explicit configuration would be needed
|
67
|
+
only in those cases where you can't follow the standard convention.
|
68
68
|
|
69
69
|
### Naming Conventions
|
70
70
|
|
@@ -78,15 +78,15 @@ of two or more words, the model class name should follow the Ruby conventions,
|
|
78
78
|
using the CamelCase form, while the table name must contain the words separated
|
79
79
|
by underscores. Examples:
|
80
80
|
|
81
|
-
* Database Table - Plural with underscores separating words (e.g., `book_clubs`)
|
81
|
+
* Database Table - Plural with underscores separating words (e.g., `book_clubs`).
|
82
82
|
* Model Class - Singular with the first letter of each word capitalized (e.g.,
|
83
|
-
`BookClub`)
|
83
|
+
`BookClub`).
|
84
84
|
|
85
85
|
| Model / Class | Table / Schema |
|
86
86
|
| ------------- | -------------- |
|
87
87
|
| `Post` | `posts` |
|
88
88
|
| `LineItem` | `line_items` |
|
89
|
-
| `Deer` | `
|
89
|
+
| `Deer` | `deers` |
|
90
90
|
| `Mouse` | `mice` |
|
91
91
|
| `Person` | `people` |
|
92
92
|
|
@@ -101,7 +101,7 @@ depending on the purpose of these columns.
|
|
101
101
|
fields that Active Record will look for when you create associations between
|
102
102
|
your models.
|
103
103
|
* **Primary keys** - By default, Active Record will use an integer column named
|
104
|
-
`id` as the table's primary key. When using [
|
104
|
+
`id` as the table's primary key. When using [Active Record
|
105
105
|
Migrations](migrations.html) to create your tables, this column will be
|
106
106
|
automatically created.
|
107
107
|
|
@@ -181,7 +181,7 @@ definition:
|
|
181
181
|
|
182
182
|
```ruby
|
183
183
|
class FunnyJoke < ActiveSupport::TestCase
|
184
|
-
set_fixture_class funny_jokes:
|
184
|
+
set_fixture_class funny_jokes: Joke
|
185
185
|
fixtures :funny_jokes
|
186
186
|
...
|
187
187
|
end
|
@@ -368,6 +368,6 @@ Rails keeps track of which files have been committed to the database and
|
|
368
368
|
provides rollback features. To actually create the table, you'd run `rake db:migrate`
|
369
369
|
and to roll it back, `rake db:rollback`.
|
370
370
|
|
371
|
-
Note that the above code is database-agnostic: it will run in MySQL,
|
372
|
-
Oracle and others. You can learn more about migrations in the
|
373
|
-
Migrations guide](migrations.html)
|
371
|
+
Note that the above code is database-agnostic: it will run in MySQL,
|
372
|
+
PostgreSQL, Oracle and others. You can learn more about migrations in the
|
373
|
+
[Active Record Migrations guide](migrations.html).
|
@@ -35,11 +35,11 @@ class User < ActiveRecord::Base
|
|
35
35
|
before_validation :ensure_login_has_a_value
|
36
36
|
|
37
37
|
protected
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
def ensure_login_has_a_value
|
39
|
+
if login.nil?
|
40
|
+
self.login = email unless email.blank?
|
41
|
+
end
|
41
42
|
end
|
42
|
-
end
|
43
43
|
end
|
44
44
|
```
|
45
45
|
|
@@ -49,8 +49,8 @@ The macro-style class methods can also receive a block. Consider using this styl
|
|
49
49
|
class User < ActiveRecord::Base
|
50
50
|
validates :login, :email, presence: true
|
51
51
|
|
52
|
-
before_create do
|
53
|
-
|
52
|
+
before_create do
|
53
|
+
self.name = login.capitalize if name.blank?
|
54
54
|
end
|
55
55
|
end
|
56
56
|
```
|
@@ -65,13 +65,13 @@ class User < ActiveRecord::Base
|
|
65
65
|
after_validation :set_location, on: [ :create, :update ]
|
66
66
|
|
67
67
|
protected
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
def normalize_name
|
69
|
+
self.name = self.name.downcase.titleize
|
70
|
+
end
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
def set_location
|
73
|
+
self.location = LocationService.query(self)
|
74
|
+
end
|
75
75
|
end
|
76
76
|
```
|
77
77
|
|
@@ -229,7 +229,7 @@ NOTE: The `find_by_*` and `find_by_*!` methods are dynamic finders generated aut
|
|
229
229
|
Skipping Callbacks
|
230
230
|
------------------
|
231
231
|
|
232
|
-
Just as with validations, it is also possible to skip callbacks
|
232
|
+
Just as with validations, it is also possible to skip callbacks by using the following methods:
|
233
233
|
|
234
234
|
* `decrement`
|
235
235
|
* `decrement_counter`
|
@@ -244,6 +244,8 @@ Just as with validations, it is also possible to skip callbacks. These methods s
|
|
244
244
|
* `update_all`
|
245
245
|
* `update_counters`
|
246
246
|
|
247
|
+
These methods should be used with caution, however, because important business rules and application logic may be kept in callbacks. Bypassing them without understanding the potential implications may lead to invalid data.
|
248
|
+
|
247
249
|
Halting Execution
|
248
250
|
-----------------
|
249
251
|
|
@@ -251,7 +253,7 @@ As you start registering new callbacks for your models, they will be queued for
|
|
251
253
|
|
252
254
|
The whole callback chain is wrapped in a transaction. If any _before_ callback method returns exactly `false` or raises an exception, the execution chain gets halted and a ROLLBACK is issued; _after_ callbacks can only accomplish that by raising an exception.
|
253
255
|
|
254
|
-
WARNING.
|
256
|
+
WARNING. Any exception that is not `ActiveRecord::Rollback` will be re-raised by Rails after the callback chain is halted. Raising an exception other than `ActiveRecord::Rollback` may break code that does not expect methods like `save` and `update_attributes` (which normally try to return `true` or `false`) to raise an exception.
|
255
257
|
|
256
258
|
Relational Callbacks
|
257
259
|
--------------------
|
@@ -392,7 +394,7 @@ By using the `after_commit` callback we can account for this case.
|
|
392
394
|
|
393
395
|
```ruby
|
394
396
|
class PictureFile < ActiveRecord::Base
|
395
|
-
after_commit :delete_picture_file_from_disk, :
|
397
|
+
after_commit :delete_picture_file_from_disk, on: [:destroy]
|
396
398
|
|
397
399
|
def delete_picture_file_from_disk
|
398
400
|
if File.exist?(filepath)
|
@@ -405,4 +407,4 @@ end
|
|
405
407
|
NOTE: the `:on` option specifies when a callback will be fired. If you
|
406
408
|
don't supply the `:on` option the callback will fire for every action.
|
407
409
|
|
408
|
-
The `after_commit` and `after_rollback` callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block. If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback.
|
410
|
+
WARNING. The `after_commit` and `after_rollback` callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block. If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback.
|
@@ -58,6 +58,7 @@ The methods are:
|
|
58
58
|
|
59
59
|
* `bind`
|
60
60
|
* `create_with`
|
61
|
+
* `distinct`
|
61
62
|
* `eager_load`
|
62
63
|
* `extending`
|
63
64
|
* `from`
|
@@ -76,7 +77,6 @@ The methods are:
|
|
76
77
|
* `reorder`
|
77
78
|
* `reverse_order`
|
78
79
|
* `select`
|
79
|
-
* `distinct`
|
80
80
|
* `uniq`
|
81
81
|
* `where`
|
82
82
|
|
@@ -91,7 +91,7 @@ The primary operation of `Model.find(options)` can be summarized as:
|
|
91
91
|
|
92
92
|
### Retrieving a Single Object
|
93
93
|
|
94
|
-
Active Record provides
|
94
|
+
Active Record provides several different ways of retrieving a single object.
|
95
95
|
|
96
96
|
#### Using a Primary Key
|
97
97
|
|
@@ -473,7 +473,7 @@ In the case of a belongs_to relationship, an association key can be used to spec
|
|
473
473
|
|
474
474
|
```ruby
|
475
475
|
Post.where(author: author)
|
476
|
-
Author.joins(:posts).where(posts: {author: author})
|
476
|
+
Author.joins(:posts).where(posts: { author: author })
|
477
477
|
```
|
478
478
|
|
479
479
|
NOTE: The values cannot be symbols. For example, you cannot do `Client.where(status: :active)`.
|
@@ -685,9 +685,9 @@ This will return single order objects for each day, but only those that are orde
|
|
685
685
|
Overriding Conditions
|
686
686
|
---------------------
|
687
687
|
|
688
|
-
### `
|
688
|
+
### `unscope`
|
689
689
|
|
690
|
-
You can specify certain conditions to be
|
690
|
+
You can specify certain conditions to be removed using the `unscope` method. For example:
|
691
691
|
|
692
692
|
```ruby
|
693
693
|
Post.where('id > 10').limit(20).order('id asc').except(:order)
|
@@ -697,27 +697,25 @@ The SQL that would be executed:
|
|
697
697
|
|
698
698
|
```sql
|
699
699
|
SELECT * FROM posts WHERE id > 10 LIMIT 20
|
700
|
-
```
|
701
|
-
|
702
|
-
### `unscope`
|
703
700
|
|
704
|
-
|
701
|
+
# Original query without `unscope`
|
702
|
+
SELECT * FROM posts WHERE id > 10 ORDER BY id asc LIMIT 20
|
705
703
|
|
706
|
-
```ruby
|
707
|
-
Post.comments.except(:order)
|
708
704
|
```
|
709
705
|
|
710
|
-
|
706
|
+
You can additionally unscope specific where clauses. For example:
|
711
707
|
|
712
708
|
```ruby
|
713
|
-
Post.
|
714
|
-
|
709
|
+
Post.where(id: 10, trashed: false).unscope(where: :id)
|
710
|
+
# => SELECT "posts".* FROM "posts" WHERE trashed = 0
|
715
711
|
```
|
716
712
|
|
717
|
-
|
713
|
+
A relation which has used `unscope` will affect any relation it is
|
714
|
+
merged in to:
|
718
715
|
|
719
716
|
```ruby
|
720
|
-
Post.
|
717
|
+
Post.order('id asc').merge(Post.unscope(:order))
|
718
|
+
# => SELECT "posts".* FROM "posts"
|
721
719
|
```
|
722
720
|
|
723
721
|
### `only`
|
@@ -732,6 +730,10 @@ The SQL that would be executed:
|
|
732
730
|
|
733
731
|
```sql
|
734
732
|
SELECT * FROM posts WHERE id > 10 ORDER BY id DESC
|
733
|
+
|
734
|
+
# Original query without `only`
|
735
|
+
SELECT "posts".* FROM "posts" WHERE (id > 10) ORDER BY id desc LIMIT 20
|
736
|
+
|
735
737
|
```
|
736
738
|
|
737
739
|
### `reorder`
|
@@ -742,7 +744,7 @@ The `reorder` method overrides the default scope order. For example:
|
|
742
744
|
class Post < ActiveRecord::Base
|
743
745
|
..
|
744
746
|
..
|
745
|
-
has_many :comments, order
|
747
|
+
has_many :comments, -> { order('posted_at DESC') }
|
746
748
|
end
|
747
749
|
|
748
750
|
Post.find(10).comments.reorder('name')
|
@@ -788,6 +790,32 @@ SELECT * FROM clients WHERE orders_count > 10 ORDER BY clients.id DESC
|
|
788
790
|
|
789
791
|
This method accepts **no** arguments.
|
790
792
|
|
793
|
+
### `rewhere`
|
794
|
+
|
795
|
+
The `rewhere` method overrides an existing, named where condition. For example:
|
796
|
+
|
797
|
+
```ruby
|
798
|
+
Post.where(trashed: true).rewhere(trashed: false)
|
799
|
+
```
|
800
|
+
|
801
|
+
The SQL that would be executed:
|
802
|
+
|
803
|
+
```sql
|
804
|
+
SELECT * FROM posts WHERE `trashed` = 0
|
805
|
+
```
|
806
|
+
|
807
|
+
In case the `rewhere` clause is not used,
|
808
|
+
|
809
|
+
```ruby
|
810
|
+
Post.where(trashed: true).where(trashed: false)
|
811
|
+
```
|
812
|
+
|
813
|
+
the SQL executed would be:
|
814
|
+
|
815
|
+
```sql
|
816
|
+
SELECT * FROM posts WHERE `trashed` = 1 AND `trashed` = 0
|
817
|
+
```
|
818
|
+
|
791
819
|
Null Relation
|
792
820
|
-------------
|
793
821
|
|
@@ -826,8 +854,6 @@ client.save
|
|
826
854
|
|
827
855
|
As `client` is explicitly set to be a readonly object, the above code will raise an `ActiveRecord::ReadOnlyRecord` exception when calling `client.save` with an updated value of _visits_.
|
828
856
|
|
829
|
-
NOTE: using `joins` without an explicit `select` will return readonly records.
|
830
|
-
|
831
857
|
Locking Records for Update
|
832
858
|
--------------------------
|
833
859
|
|
@@ -931,15 +957,13 @@ This will result in the following SQL:
|
|
931
957
|
SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id = clients.id
|
932
958
|
```
|
933
959
|
|
934
|
-
NOTE: using `joins` might return readonly records. See [readonly](active_record_querying.html#readonly-objects) for more details.
|
935
|
-
|
936
960
|
### Using Array/Hash of Named Associations
|
937
961
|
|
938
962
|
WARNING: This method only works with `INNER JOIN`.
|
939
963
|
|
940
964
|
Active Record lets you use the names of the [associations](association_basics.html) defined on the model as a shortcut for specifying `JOIN` clause for those associations when using the `joins` method.
|
941
965
|
|
942
|
-
For example, consider the following `Category`, `Post`, `
|
966
|
+
For example, consider the following `Category`, `Post`, `Comment`, `Guest` and `Tag` models:
|
943
967
|
|
944
968
|
```ruby
|
945
969
|
class Category < ActiveRecord::Base
|
@@ -1018,7 +1042,7 @@ Or, in English: "return all posts that have a comment made by a guest."
|
|
1018
1042
|
#### Joining Nested Associations (Multiple Level)
|
1019
1043
|
|
1020
1044
|
```ruby
|
1021
|
-
Category.joins(posts: [{comments: :guest}, :tags])
|
1045
|
+
Category.joins(posts: [{ comments: :guest }, :tags])
|
1022
1046
|
```
|
1023
1047
|
|
1024
1048
|
This produces:
|
@@ -1044,7 +1068,7 @@ An alternative and cleaner syntax is to nest the hash conditions:
|
|
1044
1068
|
|
1045
1069
|
```ruby
|
1046
1070
|
time_range = (Time.now.midnight - 1.day)..Time.now.midnight
|
1047
|
-
Client.joins(:orders).where(orders: {created_at: time_range})
|
1071
|
+
Client.joins(:orders).where(orders: { created_at: time_range })
|
1048
1072
|
```
|
1049
1073
|
|
1050
1074
|
This will find all clients who have orders that were created yesterday, again using a `BETWEEN` SQL expression.
|
@@ -1105,7 +1129,7 @@ This loads all the posts and the associated category and comments for each post.
|
|
1105
1129
|
#### Nested Associations Hash
|
1106
1130
|
|
1107
1131
|
```ruby
|
1108
|
-
Category.includes(posts: [{comments: :guest}, :tags]).find(1)
|
1132
|
+
Category.includes(posts: [{ comments: :guest }, :tags]).find(1)
|
1109
1133
|
```
|
1110
1134
|
|
1111
1135
|
This will find the category with id 1 and eager load all of the associated posts, the associated posts' tags and comments, and every comment's guest association.
|
@@ -1185,7 +1209,7 @@ class Post < ActiveRecord::Base
|
|
1185
1209
|
end
|
1186
1210
|
```
|
1187
1211
|
|
1188
|
-
|
1212
|
+
Call the scope as if it were a class method:
|
1189
1213
|
|
1190
1214
|
```ruby
|
1191
1215
|
Post.created_before(Time.zone.now)
|
@@ -1242,7 +1266,7 @@ One important caveat is that `default_scope` will be overridden by
|
|
1242
1266
|
|
1243
1267
|
```ruby
|
1244
1268
|
class User < ActiveRecord::Base
|
1245
|
-
default_scope
|
1269
|
+
default_scope { where state: 'pending' }
|
1246
1270
|
scope :active, -> { where state: 'active' }
|
1247
1271
|
scope :inactive, -> { where state: 'inactive' }
|
1248
1272
|
end
|
@@ -1314,6 +1338,11 @@ Client.unscoped {
|
|
1314
1338
|
Dynamic Finders
|
1315
1339
|
---------------
|
1316
1340
|
|
1341
|
+
NOTE: Dynamic finders have been deprecated in Rails 4.0 and will be
|
1342
|
+
removed in Rails 4.1. The best practice is to use Active Record scopes
|
1343
|
+
instead. You can find the deprecation gem at
|
1344
|
+
https://github.com/rails/activerecord-deprecated_finders
|
1345
|
+
|
1317
1346
|
For every field (also known as an attribute) you define in your table, Active Record provides a finder method. If you have a field called `first_name` on your `Client` model for example, you get `find_by_first_name` for free from Active Record. If you have a `locked` field on the `Client` model, you also get `find_by_locked` and methods.
|
1318
1347
|
|
1319
1348
|
You can specify an exclamation point (`!`) on the end of the dynamic finders to get them to raise an `ActiveRecord::RecordNotFound` error if they do not return any records, like `Client.find_by_name!("Ryan")`
|
@@ -1323,11 +1352,6 @@ If you want to find both by name and locked, you can chain these finders togethe
|
|
1323
1352
|
Find or Build a New Object
|
1324
1353
|
--------------------------
|
1325
1354
|
|
1326
|
-
NOTE: Some dynamic finders have been deprecated in Rails 4.0 and will be
|
1327
|
-
removed in Rails 4.1. The best practice is to use Active Record scopes
|
1328
|
-
instead. You can find the deprecation gem at
|
1329
|
-
https://github.com/rails/activerecord-deprecated_finders
|
1330
|
-
|
1331
1355
|
It's common that you need to find a record or create it if it doesn't exist. You can do that with the `find_or_create_by` and `find_or_create_by!` methods.
|
1332
1356
|
|
1333
1357
|
### `find_or_create_by`
|
@@ -1354,7 +1378,7 @@ COMMIT
|
|
1354
1378
|
|
1355
1379
|
The new record might not be saved to the database; that depends on whether validations passed or not (just like `create`).
|
1356
1380
|
|
1357
|
-
Suppose we want to set the 'locked' attribute to
|
1381
|
+
Suppose we want to set the 'locked' attribute to `false` if we're
|
1358
1382
|
creating a new record, but we don't want to include it in the query. So
|
1359
1383
|
we want to find the client named "Andy", or if that client doesn't
|
1360
1384
|
exist, create a client named "Andy" which is not locked.
|
@@ -1532,18 +1556,21 @@ Person.ids
|
|
1532
1556
|
Existence of Objects
|
1533
1557
|
--------------------
|
1534
1558
|
|
1535
|
-
If you simply want to check for the existence of the object there's a method called `exists?`.
|
1559
|
+
If you simply want to check for the existence of the object there's a method called `exists?`.
|
1560
|
+
This method will query the database using the same query as `find`, but instead of returning an
|
1561
|
+
object or collection of objects it will return either `true` or `false`.
|
1536
1562
|
|
1537
1563
|
```ruby
|
1538
1564
|
Client.exists?(1)
|
1539
1565
|
```
|
1540
1566
|
|
1541
|
-
The `exists?` method also takes multiple
|
1567
|
+
The `exists?` method also takes multiple values, but the catch is that it will return `true` if any
|
1568
|
+
one of those records exists.
|
1542
1569
|
|
1543
1570
|
```ruby
|
1544
|
-
Client.exists?(1,2,3)
|
1571
|
+
Client.exists?(id: [1,2,3])
|
1545
1572
|
# or
|
1546
|
-
Client.exists?([
|
1573
|
+
Client.exists?(name: ['John', 'Sergei'])
|
1547
1574
|
```
|
1548
1575
|
|
1549
1576
|
It's even possible to use `exists?` without any arguments on a model or a relation.
|
@@ -1552,7 +1579,8 @@ It's even possible to use `exists?` without any arguments on a model or a relati
|
|
1552
1579
|
Client.where(first_name: 'Ryan').exists?
|
1553
1580
|
```
|
1554
1581
|
|
1555
|
-
The above returns `true` if there is at least one client with the `first_name` 'Ryan' and `false`
|
1582
|
+
The above returns `true` if there is at least one client with the `first_name` 'Ryan' and `false`
|
1583
|
+
otherwise.
|
1556
1584
|
|
1557
1585
|
```ruby
|
1558
1586
|
Client.exists?
|
@@ -1602,7 +1630,7 @@ Client.where(first_name: 'Ryan').count
|
|
1602
1630
|
You can also use various finder methods on a relation for performing complex calculations:
|
1603
1631
|
|
1604
1632
|
```ruby
|
1605
|
-
Client.includes("orders").where(first_name: 'Ryan', orders: {status: 'received'}).count
|
1633
|
+
Client.includes("orders").where(first_name: 'Ryan', orders: { status: 'received' }).count
|
1606
1634
|
```
|
1607
1635
|
|
1608
1636
|
Which will execute:
|