rails 4.1.0.beta2 → 4.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/guides/assets/images/getting_started/article_with_comments.png +0 -0
- data/guides/assets/images/getting_started/challenge.png +0 -0
- data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
- data/guides/assets/images/getting_started/form_with_errors.png +0 -0
- data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
- data/guides/assets/images/getting_started/new_article.png +0 -0
- data/guides/assets/images/getting_started/rails_welcome.jpg +0 -0
- data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
- data/guides/assets/images/getting_started/{show_action_for_posts.png → show_action_for_articles.png} +0 -0
- data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
- data/guides/bug_report_templates/action_controller_gem.rb +5 -2
- data/guides/bug_report_templates/active_record_gem.rb +4 -1
- data/guides/code/getting_started/Gemfile +20 -23
- data/guides/code/getting_started/Gemfile.lock +73 -67
- data/guides/code/getting_started/app/views/layouts/application.html.erb +2 -2
- data/guides/code/getting_started/config/environments/production.rb +2 -2
- data/guides/code/getting_started/config/environments/test.rb +1 -1
- data/guides/rails_guides/helpers.rb +2 -0
- data/guides/source/3_0_release_notes.md +1 -1
- data/guides/source/4_1_release_notes.md +181 -61
- data/guides/source/action_controller_overview.md +46 -7
- data/guides/source/action_mailer_basics.md +5 -5
- data/guides/source/active_record_querying.md +18 -18
- data/guides/source/active_record_validations.md +11 -9
- data/guides/source/active_support_core_extensions.md +13 -1
- data/guides/source/api_documentation_guidelines.md +52 -2
- data/guides/source/asset_pipeline.md +54 -22
- data/guides/source/association_basics.md +13 -0
- data/guides/source/configuring.md +159 -11
- data/guides/source/contributing_to_ruby_on_rails.md +7 -6
- data/guides/source/development_dependencies_install.md +2 -0
- data/guides/source/documents.yaml +1 -1
- data/guides/source/engines.md +4 -3
- data/guides/source/form_helpers.md +10 -3
- data/guides/source/getting_started.md +525 -478
- data/guides/source/i18n.md +4 -4
- data/guides/source/initialization.md +2 -2
- data/guides/source/layouts_and_rendering.md +38 -8
- data/guides/source/migrations.md +5 -5
- data/guides/source/plugins.md +0 -1
- data/guides/source/routing.md +4 -2
- data/guides/source/security.md +47 -4
- data/guides/source/testing.md +10 -31
- data/guides/source/upgrading_ruby_on_rails.md +121 -12
- data/guides/source/working_with_javascript_in_rails.md +1 -1
- metadata +23 -24
- 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/post_with_comments.png +0 -0
- data/guides/assets/images/getting_started/rails_welcome.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_posts_new.png +0 -0
- data/guides/assets/images/getting_started/undefined_method_post_path.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
@@ -112,6 +112,10 @@ NOTE: The actual URL in this example will be encoded as "/clients?ids%5b%5d=1&id
|
|
112
112
|
|
113
113
|
The value of `params[:ids]` will now be `["1", "2", "3"]`. Note that parameter values are always strings; Rails makes no attempt to guess or cast the type.
|
114
114
|
|
115
|
+
NOTE: Values such as `[]`, `[nil]` or `[nil, nil, ...]` in `params` are replaced
|
116
|
+
with `nil` for security reasons by default. See [Security Guide](security.html#unsafe-query-generation)
|
117
|
+
for more information.
|
118
|
+
|
115
119
|
To send a hash you include the key name inside the brackets:
|
116
120
|
|
117
121
|
```html
|
@@ -568,6 +572,38 @@ end
|
|
568
572
|
|
569
573
|
Note that while for session values you set the key to `nil`, to delete a cookie value you should use `cookies.delete(:key)`.
|
570
574
|
|
575
|
+
Rails also provides a signed cookie jar and an encrypted cookie jar for storing
|
576
|
+
sensitive data. The signed cookie jar appends a cryptographic signature on the
|
577
|
+
cookie values to protect their integrity. The encrypted cookie jar encrypts the
|
578
|
+
values in addition to signing them, so that they cannot be read by the end user.
|
579
|
+
Refer to the [API documentation](http://api.rubyonrails.org/classes/ActionDispatch/Cookies.html)
|
580
|
+
for more details.
|
581
|
+
|
582
|
+
These special cookie jars use a serializer to serialize the assigned values into
|
583
|
+
strings and deserializes them into Ruby objects on read.
|
584
|
+
|
585
|
+
You can specify what serializer to use:
|
586
|
+
|
587
|
+
```ruby
|
588
|
+
Rails.application.config.action_dispatch.cookies_serializer = :json
|
589
|
+
```
|
590
|
+
|
591
|
+
The default serializer for new applications is `:json`. For compatibility with
|
592
|
+
old applications with existing cookies, `:marshal` is used when `serializer`
|
593
|
+
option is not specified.
|
594
|
+
|
595
|
+
You may also set this option to `:hybrid`, in which case Rails would transparently
|
596
|
+
deserialize existing (`Marshal`-serialized) cookies on read and re-write them in
|
597
|
+
the `JSON` format. This is useful for migrating existing applications to the
|
598
|
+
`:json` serializer.
|
599
|
+
|
600
|
+
It is also possible to pass a custom serializer that responds to `load` and
|
601
|
+
`dump`:
|
602
|
+
|
603
|
+
```ruby
|
604
|
+
Rails.application.config.action_dispatch.cookies_serializer = MyCustomSerializer
|
605
|
+
```
|
606
|
+
|
571
607
|
Rendering XML and JSON data
|
572
608
|
---------------------------
|
573
609
|
|
@@ -665,14 +701,17 @@ The first is to use a block directly with the *_action methods. The block receiv
|
|
665
701
|
```ruby
|
666
702
|
class ApplicationController < ActionController::Base
|
667
703
|
before_action do |controller|
|
668
|
-
|
704
|
+
unless controller.send(:logged_in?)
|
705
|
+
flash[:error] = "You must be logged in to access this section"
|
706
|
+
redirect_to new_login_url
|
707
|
+
end
|
669
708
|
end
|
670
709
|
end
|
671
710
|
```
|
672
711
|
|
673
712
|
Note that the filter in this case uses `send` because the `logged_in?` method is private and the filter is not run in the scope of the controller. This is not the recommended way to implement this particular filter, but in more simple cases it might be useful.
|
674
713
|
|
675
|
-
The second way is to use a class (actually, any object that responds to the right methods will do) to handle the filtering. This is useful in cases that are more complex and
|
714
|
+
The second way is to use a class (actually, any object that responds to the right methods will do) to handle the filtering. This is useful in cases that are more complex and cannot be implemented in a readable and reusable way using the two other methods. As an example, you could rewrite the login filter again to use a class:
|
676
715
|
|
677
716
|
```ruby
|
678
717
|
class ApplicationController < ActionController::Base
|
@@ -680,16 +719,16 @@ class ApplicationController < ActionController::Base
|
|
680
719
|
end
|
681
720
|
|
682
721
|
class LoginFilter
|
683
|
-
def self.
|
722
|
+
def self.before(controller)
|
684
723
|
unless controller.send(:logged_in?)
|
685
|
-
controller.flash[:error] = "You must be logged in"
|
724
|
+
controller.flash[:error] = "You must be logged in to access this section"
|
686
725
|
controller.redirect_to controller.new_login_url
|
687
726
|
end
|
688
727
|
end
|
689
728
|
end
|
690
729
|
```
|
691
730
|
|
692
|
-
Again, this is not an ideal example for this filter, because it's not run in the scope of the controller but gets the controller passed as an argument. The filter class
|
731
|
+
Again, this is not an ideal example for this filter, because it's not run in the scope of the controller but gets the controller passed as an argument. The filter class must implement a method with the same name as the filter, so for the `before_action` filter the class must implement a `before` method, and so on. The `around` method must `yield` to execute the action.
|
693
732
|
|
694
733
|
Request Forgery Protection
|
695
734
|
--------------------------
|
@@ -794,7 +833,7 @@ class AdminsController < ApplicationController
|
|
794
833
|
end
|
795
834
|
```
|
796
835
|
|
797
|
-
With this in place, you can create namespaced controllers that inherit from `
|
836
|
+
With this in place, you can create namespaced controllers that inherit from `AdminsController`. The filter will thus be run for all actions in those controllers, protecting them with HTTP basic authentication.
|
798
837
|
|
799
838
|
### HTTP Digest Authentication
|
800
839
|
|
@@ -1049,7 +1088,7 @@ class ApplicationController < ActionController::Base
|
|
1049
1088
|
private
|
1050
1089
|
|
1051
1090
|
def record_not_found
|
1052
|
-
render
|
1091
|
+
render plain: "404 Not Found", status: 404
|
1053
1092
|
end
|
1054
1093
|
end
|
1055
1094
|
```
|
@@ -138,7 +138,7 @@ When you call the `mail` method now, Action Mailer will detect the two templates
|
|
138
138
|
|
139
139
|
Mailers are really just another way to render a view. Instead of rendering a
|
140
140
|
view and sending out the HTTP protocol, they are just sending it out through the
|
141
|
-
|
141
|
+
email protocols instead. Due to this, it makes sense to just have your
|
142
142
|
controller tell the Mailer to send an email when a user is successfully created.
|
143
143
|
|
144
144
|
Setting this up is painfully simple.
|
@@ -164,7 +164,7 @@ class UsersController < ApplicationController
|
|
164
164
|
|
165
165
|
respond_to do |format|
|
166
166
|
if @user.save
|
167
|
-
# Tell the UserMailer to send a welcome
|
167
|
+
# Tell the UserMailer to send a welcome email after save
|
168
168
|
UserMailer.welcome_email(@user).deliver
|
169
169
|
|
170
170
|
format.html { redirect_to(@user, notice: 'User was successfully created.') }
|
@@ -611,7 +611,7 @@ files (environment.rb, production.rb, etc...)
|
|
611
611
|
|`smtp_settings`|Allows detailed configuration for `:smtp` delivery method:<ul><li>`:address` - Allows you to use a remote mail server. Just change it from its default "localhost" setting.</li><li>`:port` - On the off chance that your mail server doesn't run on port 25, you can change it.</li><li>`:domain` - If you need to specify a HELO domain, you can do it here.</li><li>`:user_name` - If your mail server requires authentication, set the username in this setting.</li><li>`:password` - If your mail server requires authentication, set the password in this setting.</li><li>`:authentication` - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of `:plain`, `:login`, `:cram_md5`.</li><li>`:enable_starttls_auto` - Set this to `false` if there is a problem with your server certificate that you cannot resolve.</li></ul>|
|
612
612
|
|`sendmail_settings`|Allows you to override options for the `:sendmail` delivery method.<ul><li>`:location` - The location of the sendmail executable. Defaults to `/usr/sbin/sendmail`.</li><li>`:arguments` - The command line arguments to be passed to sendmail. Defaults to `-i -t`.</li></ul>|
|
613
613
|
|`raise_delivery_errors`|Whether or not errors should be raised if the email fails to be delivered. This only works if the external email server is configured for immediate delivery.|
|
614
|
-
|`delivery_method`|Defines a delivery method. Possible values are
|
614
|
+
|`delivery_method`|Defines a delivery method. Possible values are:<ul><li>`:smtp` (default), can be configured by using `config.action_mailer.smtp_settings`.</li><li>`:sendmail`, can be configured by using `config.action_mailer.sendmail_settings`.</li><li>`:file`: save emails to files; can be configured by using `config.action_mailer.file_settings`.</li><li>`:test`: save emails to `ActionMailer::Base.deliveries` array.</li></ul>See [API docs](http://api.rubyonrails.org/classes/ActionMailer/Base.html) for more info.|
|
615
615
|
|`perform_deliveries`|Determines whether deliveries are actually carried out when the `deliver` method is invoked on the Mail message. By default they are, but this can be turned off to help functional testing.|
|
616
616
|
|`deliveries`|Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful for unit and functional testing.|
|
617
617
|
|`default_options`|Allows you to set default values for the `mail` method options (`:from`, `:reply_to`, etc.).|
|
@@ -639,8 +639,8 @@ config.action_mailer.default_options = {from: 'no-reply@example.com'}
|
|
639
639
|
|
640
640
|
### Action Mailer Configuration for Gmail
|
641
641
|
|
642
|
-
As Action Mailer now uses the Mail gem, this
|
643
|
-
`config/environments/$RAILS_ENV.rb` file:
|
642
|
+
As Action Mailer now uses the [Mail gem](https://github.com/mikel/mail), this
|
643
|
+
becomes as simple as adding to your `config/environments/$RAILS_ENV.rb` file:
|
644
644
|
|
645
645
|
```ruby
|
646
646
|
config.action_mailer.delivery_method = :smtp
|
@@ -707,7 +707,7 @@ You can additionally unscope specific where clauses. For example:
|
|
707
707
|
|
708
708
|
```ruby
|
709
709
|
Post.where(id: 10, trashed: false).unscope(where: :id)
|
710
|
-
#
|
710
|
+
# SELECT "posts".* FROM "posts" WHERE trashed = 0
|
711
711
|
```
|
712
712
|
|
713
713
|
A relation which has used `unscope` will affect any relation it is
|
@@ -715,7 +715,7 @@ merged in to:
|
|
715
715
|
|
716
716
|
```ruby
|
717
717
|
Post.order('id asc').merge(Post.unscope(:order))
|
718
|
-
#
|
718
|
+
# SELECT "posts".* FROM "posts"
|
719
719
|
```
|
720
720
|
|
721
721
|
### `only`
|
@@ -1242,26 +1242,26 @@ class User < ActiveRecord::Base
|
|
1242
1242
|
end
|
1243
1243
|
|
1244
1244
|
User.active.inactive
|
1245
|
-
#
|
1245
|
+
# SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND "users"."state" = 'inactive'
|
1246
1246
|
```
|
1247
1247
|
|
1248
1248
|
We can mix and match `scope` and `where` conditions and the final sql
|
1249
|
-
will have all conditions joined with `AND
|
1249
|
+
will have all conditions joined with `AND`.
|
1250
1250
|
|
1251
1251
|
```ruby
|
1252
1252
|
User.active.where(state: 'finished')
|
1253
|
-
#
|
1253
|
+
# SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND "users"."state" = 'finished'
|
1254
1254
|
```
|
1255
1255
|
|
1256
1256
|
If we do want the `last where clause` to win then `Relation#merge` can
|
1257
|
-
be used
|
1257
|
+
be used.
|
1258
1258
|
|
1259
1259
|
```ruby
|
1260
1260
|
User.active.merge(User.inactive)
|
1261
|
-
#
|
1261
|
+
# SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
|
1262
1262
|
```
|
1263
1263
|
|
1264
|
-
One important caveat is that `default_scope` will be
|
1264
|
+
One important caveat is that `default_scope` will be prepended in
|
1265
1265
|
`scope` and `where` conditions.
|
1266
1266
|
|
1267
1267
|
```ruby
|
@@ -1272,16 +1272,16 @@ class User < ActiveRecord::Base
|
|
1272
1272
|
end
|
1273
1273
|
|
1274
1274
|
User.all
|
1275
|
-
#
|
1275
|
+
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
|
1276
1276
|
|
1277
1277
|
User.active
|
1278
|
-
#
|
1278
|
+
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'active'
|
1279
1279
|
|
1280
1280
|
User.where(state: 'inactive')
|
1281
|
-
#
|
1281
|
+
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'inactive'
|
1282
1282
|
```
|
1283
1283
|
|
1284
|
-
As you can see above the `default_scope` is being
|
1284
|
+
As you can see above the `default_scope` is being merged in both
|
1285
1285
|
`scope` and `where` conditions.
|
1286
1286
|
|
1287
1287
|
|
@@ -1338,11 +1338,6 @@ Client.unscoped {
|
|
1338
1338
|
Dynamic Finders
|
1339
1339
|
---------------
|
1340
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
|
-
|
1346
1341
|
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.
|
1347
1342
|
|
1348
1343
|
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")`
|
@@ -1352,6 +1347,11 @@ If you want to find both by name and locked, you can chain these finders togethe
|
|
1352
1347
|
Find or Build a New Object
|
1353
1348
|
--------------------------
|
1354
1349
|
|
1350
|
+
NOTE: Some dynamic finders have been deprecated in Rails 4.0 and will be
|
1351
|
+
removed in Rails 4.1. The best practice is to use Active Record scopes
|
1352
|
+
instead. You can find the deprecation gem at
|
1353
|
+
https://github.com/rails/activerecord-deprecated_finders
|
1354
|
+
|
1355
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.
|
1356
1356
|
|
1357
1357
|
### `find_or_create_by`
|
@@ -1455,7 +1455,7 @@ If you'd like to use your own SQL to find records in a table you can use `find_b
|
|
1455
1455
|
```ruby
|
1456
1456
|
Client.find_by_sql("SELECT * FROM clients
|
1457
1457
|
INNER JOIN orders ON clients.id = orders.client_id
|
1458
|
-
ORDER clients.created_at desc")
|
1458
|
+
ORDER BY clients.created_at desc")
|
1459
1459
|
```
|
1460
1460
|
|
1461
1461
|
`find_by_sql` provides you with a simple way of making custom calls to the database and retrieving instantiated objects.
|
@@ -575,7 +575,9 @@ This helper validates that the attribute's value is unique right before the
|
|
575
575
|
object gets saved. It does not create a uniqueness constraint in the database,
|
576
576
|
so it may happen that two different database connections create two records
|
577
577
|
with the same value for a column that you intend to be unique. To avoid that,
|
578
|
-
you must create a unique index in your database.
|
578
|
+
you must create a unique index on both columns in your database. See
|
579
|
+
[the MySQL manual](http://dev.mysql.com/doc/refman/5.6/en/multiple-column-indexes.html)
|
580
|
+
for more details about multiple column indexes.
|
579
581
|
|
580
582
|
```ruby
|
581
583
|
class Account < ActiveRecord::Base
|
@@ -616,10 +618,6 @@ The default error message is _"has already been taken"_.
|
|
616
618
|
This helper passes the record to a separate class for validation.
|
617
619
|
|
618
620
|
```ruby
|
619
|
-
class Person < ActiveRecord::Base
|
620
|
-
validates_with GoodnessValidator
|
621
|
-
end
|
622
|
-
|
623
621
|
class GoodnessValidator < ActiveModel::Validator
|
624
622
|
def validate(record)
|
625
623
|
if record.first_name == "Evil"
|
@@ -627,6 +625,10 @@ class GoodnessValidator < ActiveModel::Validator
|
|
627
625
|
end
|
628
626
|
end
|
629
627
|
end
|
628
|
+
|
629
|
+
class Person < ActiveRecord::Base
|
630
|
+
validates_with GoodnessValidator
|
631
|
+
end
|
630
632
|
```
|
631
633
|
|
632
634
|
NOTE: Errors added to `record.errors[:base]` relate to the state of the record
|
@@ -644,10 +646,6 @@ Like all other validations, `validates_with` takes the `:if`, `:unless` and
|
|
644
646
|
validator class as `options`:
|
645
647
|
|
646
648
|
```ruby
|
647
|
-
class Person < ActiveRecord::Base
|
648
|
-
validates_with GoodnessValidator, fields: [:first_name, :last_name]
|
649
|
-
end
|
650
|
-
|
651
649
|
class GoodnessValidator < ActiveModel::Validator
|
652
650
|
def validate(record)
|
653
651
|
if options[:fields].any?{|field| record.send(field) == "Evil" }
|
@@ -655,6 +653,10 @@ class GoodnessValidator < ActiveModel::Validator
|
|
655
653
|
end
|
656
654
|
end
|
657
655
|
end
|
656
|
+
|
657
|
+
class Person < ActiveRecord::Base
|
658
|
+
validates_with GoodnessValidator, fields: [:first_name, :last_name]
|
659
|
+
end
|
658
660
|
```
|
659
661
|
|
660
662
|
Note that the validator will be initialized *only once* for the whole application
|
@@ -424,7 +424,7 @@ NOTE: Defined in `active_support/core_ext/object/with_options.rb`.
|
|
424
424
|
|
425
425
|
### JSON support
|
426
426
|
|
427
|
-
Active Support provides a better implementation of `to_json` than the
|
427
|
+
Active Support provides a better implementation of `to_json` than the `json` gem ordinarily provides for Ruby objects. This is because some classes, like `Hash`, `OrderedHash` and `Process::Status` need special handling in order to provide a proper JSON representation.
|
428
428
|
|
429
429
|
NOTE: Defined in `active_support/core_ext/object/json.rb`.
|
430
430
|
|
@@ -1403,6 +1403,8 @@ The third argument, `indent_empty_lines`, is a flag that says whether empty line
|
|
1403
1403
|
|
1404
1404
|
The `indent!` method performs indentation in-place.
|
1405
1405
|
|
1406
|
+
NOTE: Defined in `active_support/core_ext/string/indent.rb`.
|
1407
|
+
|
1406
1408
|
### Access
|
1407
1409
|
|
1408
1410
|
#### `at(position)`
|
@@ -2907,6 +2909,16 @@ The method `with_indifferent_access` returns an `ActiveSupport::HashWithIndiffer
|
|
2907
2909
|
|
2908
2910
|
NOTE: Defined in `active_support/core_ext/hash/indifferent_access.rb`.
|
2909
2911
|
|
2912
|
+
### Compacting
|
2913
|
+
|
2914
|
+
The methods `compact` and `compact!` return a Hash without items with `nil` value.
|
2915
|
+
|
2916
|
+
```ruby
|
2917
|
+
{a: 1, b: 2, c: nil}.compact # => {a: 1, b: 2}
|
2918
|
+
```
|
2919
|
+
|
2920
|
+
NOTE: Defined in `active_support/core_ext/hash/compact.rb`.
|
2921
|
+
|
2910
2922
|
Extensions to `Regexp`
|
2911
2923
|
----------------------
|
2912
2924
|
|
@@ -67,7 +67,7 @@ used. Instead of:
|
|
67
67
|
English
|
68
68
|
-------
|
69
69
|
|
70
|
-
Please use American English (<em>color</em>, <em>center</em>, <em>modularize</em>, etc)
|
70
|
+
Please use American English (<em>color</em>, <em>center</em>, <em>modularize</em>, etc). See [a list of American and British English spelling differences here](http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences).
|
71
71
|
|
72
72
|
Example Code
|
73
73
|
------------
|
@@ -128,6 +128,53 @@ On the other hand, regular comments do not use an arrow:
|
|
128
128
|
# polymorphic_url(record) # same as comment_url(record)
|
129
129
|
```
|
130
130
|
|
131
|
+
Booleans
|
132
|
+
--------
|
133
|
+
|
134
|
+
In predicates and flags prefer documenting boolean semantics over exact values.
|
135
|
+
|
136
|
+
When "true" or "false" are used as defined in Ruby use regular font. The
|
137
|
+
singletons `true` and `false` need fixed-width font. Please avoid terms like
|
138
|
+
"truthy", Ruby defines what is true and false in the language, and thus those
|
139
|
+
words have a technical meaning and need no substitutes.
|
140
|
+
|
141
|
+
As a rule of thumb, do not document singletons unless absolutely necessary. That
|
142
|
+
prevents artificial constructs like `!!` or ternaries, allows refactors, and the
|
143
|
+
code does not need to rely on the exact values returned by methods being called
|
144
|
+
in the implementation.
|
145
|
+
|
146
|
+
For example:
|
147
|
+
|
148
|
+
```markdown
|
149
|
+
`config.action_mailer.perform_deliveries` specifies whether mail will actually be delivered and is true by default
|
150
|
+
```
|
151
|
+
|
152
|
+
the user does not need to know which is the actual default value of the flag,
|
153
|
+
and so we only document its boolean semantics.
|
154
|
+
|
155
|
+
An example with a predicate:
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
# Returns true if the collection is empty.
|
159
|
+
#
|
160
|
+
# If the collection has been loaded
|
161
|
+
# it is equivalent to <tt>collection.size.zero?</tt>. If the
|
162
|
+
# collection has not been loaded, it is equivalent to
|
163
|
+
# <tt>collection.exists?</tt>. If the collection has not already been
|
164
|
+
# loaded and you are going to fetch the records anyway it is better to
|
165
|
+
# check <tt>collection.length.zero?</tt>.
|
166
|
+
def empty?
|
167
|
+
if loaded?
|
168
|
+
size.zero?
|
169
|
+
else
|
170
|
+
@target.blank? && !scope.exists?
|
171
|
+
end
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
The API is careful not to commit to any particular value, the method has
|
176
|
+
predicate semantics, that's enough.
|
177
|
+
|
131
178
|
Filenames
|
132
179
|
---------
|
133
180
|
|
@@ -163,7 +210,10 @@ class Array
|
|
163
210
|
end
|
164
211
|
```
|
165
212
|
|
166
|
-
WARNING: Using
|
213
|
+
WARNING: Using `+...+` for fixed-width font only works with simple content like
|
214
|
+
ordinary method names, symbols, paths (with forward slashes), etc. Please use
|
215
|
+
`<tt>...</tt>` for everything else, notably class or module names with a
|
216
|
+
namespace as in `<tt>ActiveRecord::Base</tt>`.
|
167
217
|
|
168
218
|
### Regular Font
|
169
219
|
|
@@ -26,14 +26,14 @@ been extracted out of the framework into the
|
|
26
26
|
|
27
27
|
The asset pipeline is enabled by default.
|
28
28
|
|
29
|
-
You can disable the asset pipeline while creating a new application by
|
29
|
+
You can disable the asset pipeline while creating a new application by
|
30
30
|
passing the `--skip-sprockets` option.
|
31
31
|
|
32
32
|
```bash
|
33
33
|
rails new appname --skip-sprockets
|
34
34
|
```
|
35
35
|
|
36
|
-
Rails 4 automatically adds the `sass-rails`, `coffee-rails` and `uglifier`
|
36
|
+
Rails 4 automatically adds the `sass-rails`, `coffee-rails` and `uglifier`
|
37
37
|
gems to your Gemfile, which are used by Sprockets for asset compression:
|
38
38
|
|
39
39
|
```ruby
|
@@ -42,7 +42,7 @@ gem 'uglifier'
|
|
42
42
|
gem 'coffee-rails'
|
43
43
|
```
|
44
44
|
|
45
|
-
Using the `--skip-sprockets` option will prevent Rails 4 from adding
|
45
|
+
Using the `--skip-sprockets` option will prevent Rails 4 from adding
|
46
46
|
`sass-rails` and `uglifier` to Gemfile, so if you later want to enable
|
47
47
|
the asset pipeline you will have to add those gems to your Gemfile. Also,
|
48
48
|
creating an application with the `--skip-sprockets` option will generate
|
@@ -54,7 +54,7 @@ the comment operator on that line to later enable the asset pipeline:
|
|
54
54
|
# require "sprockets/railtie"
|
55
55
|
```
|
56
56
|
|
57
|
-
To set asset compression methods, set the appropriate configuration options
|
57
|
+
To set asset compression methods, set the appropriate configuration options
|
58
58
|
in `production.rb` - `config.assets.css_compressor` for your CSS and
|
59
59
|
`config.assets.js_compressor` for your Javascript:
|
60
60
|
|
@@ -228,7 +228,7 @@ Pipeline assets can be placed inside an application in one of three locations:
|
|
228
228
|
* `app/assets` is for assets that are owned by the application, such as custom
|
229
229
|
images, JavaScript files or stylesheets.
|
230
230
|
|
231
|
-
* `lib/assets` is for your own libraries' code that doesn't really fit into the
|
231
|
+
* `lib/assets` is for your own libraries' code that doesn't really fit into the
|
232
232
|
scope of the application or those libraries which are shared across applications.
|
233
233
|
|
234
234
|
* `vendor/assets` is for assets that are owned by outside entities, such as
|
@@ -350,8 +350,8 @@ Alternatively, a request for a file with an MD5 hash such as
|
|
350
350
|
way. How these hashes are generated is covered in the [In
|
351
351
|
Production](#in-production) section later on in this guide.
|
352
352
|
|
353
|
-
Sprockets will also look through the paths specified in `config.assets.paths`,
|
354
|
-
which includes the standard application paths and any paths added by Rails
|
353
|
+
Sprockets will also look through the paths specified in `config.assets.paths`,
|
354
|
+
which includes the standard application paths and any paths added by Rails
|
355
355
|
engines.
|
356
356
|
|
357
357
|
Images can also be organized into subdirectories if required, and then can be
|
@@ -496,16 +496,11 @@ In this example, `require_self` is used. This puts the CSS contained within the
|
|
496
496
|
file (if any) at the precise location of the `require_self` call. If
|
497
497
|
`require_self` is called more than once, only the last call is respected.
|
498
498
|
|
499
|
-
NOTE. If you want to use multiple Sass files, you should generally use the [Sass
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
document they were defined in. You can do file globbing as well using
|
505
|
-
`@import "*"`, and `@import "**/*"` to add the whole tree equivalent to how
|
506
|
-
`require_tree` works. Check the [sass-rails
|
507
|
-
documentation](https://github.com/rails/sass-rails#features) for more info and
|
508
|
-
important caveats.
|
499
|
+
NOTE. If you want to use multiple Sass files, you should generally use the [Sass `@import` rule](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import)
|
500
|
+
instead of these Sprockets directives. Using Sprockets directives all Sass files exist within
|
501
|
+
their own scope, making variables or mixins only available within the document they were defined in.
|
502
|
+
You can do file globbing as well using `@import "*"`, and `@import "**/*"` to add the whole tree
|
503
|
+
equivalent to how `require_tree` works. Check the [sass-rails documentation](https://github.com/rails/sass-rails#features) for more info and important caveats.
|
509
504
|
|
510
505
|
You can have as many manifest files as you need. For example, the `admin.css`
|
511
506
|
and `admin.js` manifest could contain the JS and CSS files that are used for the
|
@@ -532,7 +527,7 @@ and CSS file. The example used before was a controller called "projects", which
|
|
532
527
|
generated an `app/assets/javascripts/projects.js.coffee` and an
|
533
528
|
`app/assets/stylesheets/projects.css.scss` file.
|
534
529
|
|
535
|
-
In development mode, or if the asset pipeline is disabled, when these files are
|
530
|
+
In development mode, or if the asset pipeline is disabled, when these files are
|
536
531
|
requested they are processed by the processors provided by the `coffee-script`
|
537
532
|
and `sass` gems and then sent back to the browser as JavaScript and CSS
|
538
533
|
respectively. When asset pipelining is enabled, these files are preprocessed and
|
@@ -577,6 +572,33 @@ would generate this HTML:
|
|
577
572
|
|
578
573
|
The `body` param is required by Sprockets.
|
579
574
|
|
575
|
+
### Runtime Error Checking
|
576
|
+
|
577
|
+
By default the asset pipeline will check for potential errors in development mode during
|
578
|
+
runtime. To disable this behavior you can set:
|
579
|
+
|
580
|
+
```ruby
|
581
|
+
config.assets.raise_runtime_errors = false
|
582
|
+
```
|
583
|
+
|
584
|
+
When `raise_runtime_errors` is set to `false` sprockets will not check that dependencies of assets are declared properly. Here is a scenario where you must tell the asset pipeline about a dependency:
|
585
|
+
|
586
|
+
If you have `application.css.erb` that references `logo.png` like this:
|
587
|
+
|
588
|
+
```css
|
589
|
+
#logo { background: url(<%= asset_data_uri 'logo.png' %>) }
|
590
|
+
```
|
591
|
+
|
592
|
+
Then you must declare that `logo.png` is a dependency of `application.css.erb`, so when the image gets re-compiled, the css file does as well. You can do this using the `//= depend_on_asset` declaration:
|
593
|
+
|
594
|
+
```css
|
595
|
+
//= depend_on_asset "logo.png"
|
596
|
+
#logo { background: url(<%= asset_data_uri 'logo.png' %>) }
|
597
|
+
```
|
598
|
+
|
599
|
+
Without this declaration you may experience strange behavior when pushing to production that is difficult to debug. When you have `raise_runtime_errors` set to `true`, dependencies will be checked at runtime so you can ensure that all dependencies are met.
|
600
|
+
|
601
|
+
|
580
602
|
### Turning Debugging Off
|
581
603
|
|
582
604
|
You can turn off debug mode by updating `config/environments/development.rb` to
|
@@ -611,7 +633,7 @@ Debug mode can also be enabled in Rails helper methods:
|
|
611
633
|
|
612
634
|
The `:debug` option is redundant if debug mode is already on.
|
613
635
|
|
614
|
-
You can also enable compression in development mode as a sanity check, and
|
636
|
+
You can also enable compression in development mode as a sanity check, and
|
615
637
|
disable it on-demand as required for debugging.
|
616
638
|
|
617
639
|
In Production
|
@@ -911,7 +933,7 @@ Customizing the Pipeline
|
|
911
933
|
|
912
934
|
### CSS Compression
|
913
935
|
|
914
|
-
|
936
|
+
One of the options for compressing CSS is YUI. The [YUI CSS
|
915
937
|
compressor](http://yui.github.io/yuicompressor/css.html) provides
|
916
938
|
minification.
|
917
939
|
|
@@ -921,6 +943,11 @@ gem.
|
|
921
943
|
```ruby
|
922
944
|
config.assets.css_compressor = :yui
|
923
945
|
```
|
946
|
+
The other option for compressing CSS if you have the sass-rails gem installed is
|
947
|
+
|
948
|
+
```ruby
|
949
|
+
config.assets.css_compressor = :sass
|
950
|
+
```
|
924
951
|
|
925
952
|
### JavaScript Compression
|
926
953
|
|
@@ -991,7 +1018,8 @@ The X-Sendfile header is a directive to the web server to ignore the response
|
|
991
1018
|
from the application, and instead serve a specified file from disk. This option
|
992
1019
|
is off by default, but can be enabled if your server supports it. When enabled,
|
993
1020
|
this passes responsibility for serving the file to the web server, which is
|
994
|
-
faster.
|
1021
|
+
faster. Have a look at [send_file](http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file)
|
1022
|
+
on how to use this feature.
|
995
1023
|
|
996
1024
|
Apache and nginx support this option, which can be enabled in
|
997
1025
|
`config/environments/production.rb`:
|
@@ -1006,6 +1034,10 @@ option, take care to paste this configuration option only into `production.rb`
|
|
1006
1034
|
and any other environments you define with production behavior (not
|
1007
1035
|
`application.rb`).
|
1008
1036
|
|
1037
|
+
TIP: For further details have a look at the docs of your production web server:
|
1038
|
+
- [Apache](https://tn123.org/mod_xsendfile/)
|
1039
|
+
- [Nginx](http://wiki.nginx.org/XSendfile)
|
1040
|
+
|
1009
1041
|
Assets Cache Store
|
1010
1042
|
------------------
|
1011
1043
|
|
@@ -1118,7 +1150,7 @@ config.assets.digest = true
|
|
1118
1150
|
```
|
1119
1151
|
|
1120
1152
|
Rails 4 no longer sets default config values for Sprockets in `test.rb`, so
|
1121
|
-
`test.rb` now
|
1153
|
+
`test.rb` now requires Sprockets configuration. The old defaults in the test
|
1122
1154
|
environment are: `config.assets.compile = true`, `config.assets.compress =
|
1123
1155
|
false`, `config.assets.debug = false` and `config.assets.digest = false`.
|
1124
1156
|
|