railties 3.0.0.rc → 3.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/CHANGELOG +80 -75
  2. data/README.rdoc +1 -1
  3. data/guides/assets/stylesheets/main.css +14 -14
  4. data/guides/rails_guides.rb +20 -1
  5. data/guides/rails_guides/generator.rb +7 -7
  6. data/guides/source/2_3_release_notes.textile +5 -5
  7. data/guides/source/3_0_release_notes.textile +4 -3
  8. data/guides/source/action_controller_overview.textile +32 -17
  9. data/guides/source/action_view_overview.textile +44 -44
  10. data/guides/source/active_record_basics.textile +2 -2
  11. data/guides/source/active_record_querying.textile +7 -7
  12. data/guides/source/active_record_validations_callbacks.textile +20 -20
  13. data/guides/source/active_support_core_extensions.textile +370 -198
  14. data/guides/source/ajax_on_rails.textile +17 -17
  15. data/guides/source/api_documentation_guidelines.textile +3 -3
  16. data/guides/source/association_basics.textile +2 -2
  17. data/guides/source/caching_with_rails.textile +5 -5
  18. data/guides/source/command_line.textile +8 -8
  19. data/guides/source/configuring.textile +6 -6
  20. data/guides/source/contributing_to_rails.textile +14 -11
  21. data/guides/source/debugging_rails_applications.textile +8 -6
  22. data/guides/source/form_helpers.textile +1 -1
  23. data/guides/source/generators.textile +34 -30
  24. data/guides/source/getting_started.textile +13 -13
  25. data/guides/source/i18n.textile +12 -1
  26. data/guides/source/index.html.erb +4 -0
  27. data/guides/source/initialization.textile +67 -72
  28. data/guides/source/layout.html.erb +1 -0
  29. data/guides/source/layouts_and_rendering.textile +9 -9
  30. data/guides/source/nested_model_forms.textile +7 -7
  31. data/guides/source/plugins.textile +1 -1
  32. data/guides/source/rails_application_templates.textile +2 -2
  33. data/guides/source/routing.textile +27 -5
  34. data/guides/source/security.textile +6 -6
  35. data/guides/w3c_validator.rb +9 -9
  36. data/lib/rails/application.rb +1 -0
  37. data/lib/rails/application/configuration.rb +1 -1
  38. data/lib/rails/code_statistics.rb +4 -4
  39. data/lib/rails/commands.rb +1 -1
  40. data/lib/rails/commands/dbconsole.rb +1 -1
  41. data/lib/rails/commands/plugin.rb +1 -1
  42. data/lib/rails/commands/runner.rb +1 -1
  43. data/lib/rails/deprecation.rb +31 -52
  44. data/lib/rails/engine.rb +1 -1
  45. data/lib/rails/engine/configuration.rb +28 -1
  46. data/lib/rails/generators.rb +2 -2
  47. data/lib/rails/generators/actions.rb +3 -3
  48. data/lib/rails/generators/active_model.rb +3 -3
  49. data/lib/rails/generators/base.rb +1 -1
  50. data/lib/rails/generators/rails/app/app_generator.rb +9 -3
  51. data/lib/rails/generators/rails/app/templates/Gemfile +2 -2
  52. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +4 -13
  53. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +1 -1
  54. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +4 -0
  55. data/lib/rails/generators/rails/app/templates/config/routes.rb +4 -4
  56. data/lib/rails/generators/rails/app/templates/public/index.html +0 -23
  57. data/lib/rails/generators/rails/app/templates/public/javascripts/effects.js +1 -1
  58. data/lib/rails/generators/rails/generator/USAGE +3 -2
  59. data/lib/rails/generators/rails/migration/USAGE +4 -4
  60. data/lib/rails/generators/rails/plugin/USAGE +1 -1
  61. data/lib/rails/generators/rails/resource/resource_generator.rb +2 -2
  62. data/lib/rails/generators/test_case.rb +1 -1
  63. data/lib/rails/info_controller.rb +1 -1
  64. data/lib/rails/plugin.rb +1 -1
  65. data/lib/rails/rack/log_tailer.rb +2 -5
  66. data/lib/rails/railtie.rb +22 -22
  67. data/lib/rails/script_rails_loader.rb +2 -2
  68. data/lib/rails/tasks/documentation.rake +5 -5
  69. data/lib/rails/tasks/framework.rake +1 -1
  70. data/lib/rails/tasks/routes.rake +23 -9
  71. data/lib/rails/test_unit/testing.rake +3 -2
  72. data/lib/rails/version.rb +1 -1
  73. metadata +10 -10
@@ -16,7 +16,7 @@ Active Record is the M in "MVC":getting_started.html#the-mvc-architecture - the
16
16
 
17
17
  h4. The Active Record Pattern
18
18
 
19
- Active Record was described by Martin Fowler in his book _Patterns of Enterprise Application Architecture_. In Active Record, objects carry both persistent data and behavior which operates on that data. Active Record takes the opinion that ensuring data access logic is part of the object will educate users of that object on how to write to and read from the database.
19
+ Active Record was described by Martin Fowler in his book _Patterns of Enterprise Application Architecture_. In Active Record, objects carry both persistent data and behavior which operates on that data. Active Record takes the opinion that ensuring data access logic is part of the object will educate users of that object on how to write to and read from the database.
20
20
 
21
21
  h4. Object Relational Mapping
22
22
 
@@ -132,7 +132,7 @@ CRUD is an acronym for the four verbs we use to operate on data: *C*reate, *R*ea
132
132
 
133
133
  h4. Create
134
134
 
135
- Active Record objects can be created from a hash, a block or have its attributes manually set after creation. The _new_ method will return a new object while _create_ will return the object and save it to the database.
135
+ Active Record objects can be created from a hash, a block or have its attributes manually set after creation. The _new_ method will return a new object while _create_ will return the object and save it to the database.
136
136
 
137
137
  For example, given a model +User+ with attributes of +name+ and +occupation+, the _create_ method call will create and save a new record into the database:
138
138
 
@@ -153,7 +153,7 @@ SELECT * FROM clients WHERE (clients.id IN (1,10))
153
153
 
154
154
  h4. Retrieving Multiple Objects in Batches
155
155
 
156
- Sometimes you need to iterate over a large set of records. For example to send a newsletter to all users, to export some data, etc.
156
+ Sometimes you need to iterate over a large set of records. For example to send a newsletter to all users, to export some data, etc.
157
157
 
158
158
  The following may seem very straight forward at first:
159
159
 
@@ -674,7 +674,7 @@ Post.joins(:category, :comments)
674
674
  This produces:
675
675
 
676
676
  <sql>
677
- SELECT posts.* FROM posts
677
+ SELECT posts.* FROM posts
678
678
  INNER JOIN categories ON posts.category_id = categories.id
679
679
  INNER JOIN comments ON comments.post_id = posts.id
680
680
  </sql>
@@ -753,7 +753,7 @@ h4. Eager Loading Multiple Associations
753
753
 
754
754
  Active Record lets you eager load any number of associations with a single +Model.find+ call by using an array, hash, or a nested hash of array/hash with the +includes+ method.
755
755
 
756
- h5. Array of Multiple Associations
756
+ h5. Array of Multiple Associations
757
757
 
758
758
  <ruby>
759
759
  Post.includes(:category, :comments)
@@ -764,14 +764,14 @@ This loads all the posts and the associated category and comments for each post.
764
764
  h5. Nested Associations Hash
765
765
 
766
766
  <ruby>
767
- Category.find(1).includes(:posts => [{:comments => :guest}, :tags])
767
+ Category.includes(:posts => [{:comments => :guest}, :tags]).find(1)
768
768
  </ruby>
769
769
 
770
770
  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.
771
771
 
772
772
  h4. Specifying Conditions on Eager Loaded Associations
773
773
 
774
- Even though Active Record lets you specify conditions on the eager loaded associations just like +joins+, the recommended way is to use "joins":#joining-tables instead.
774
+ Even though Active Record lets you specify conditions on the eager loaded associations just like +joins+, the recommended way is to use "joins":#joining-tables instead.
775
775
 
776
776
  h3. Dynamic Finders
777
777
 
@@ -807,8 +807,8 @@ h3. Finding by SQL
807
807
  If you'd like to use your own SQL to find records in a table you can use +find_by_sql+. The +find_by_sql+ method will return an array of objects even if the underlying query returns just a single record. For example you could run this query:
808
808
 
809
809
  <ruby>
810
- Client.find_by_sql("SELECT * FROM clients
811
- INNER JOIN orders ON clients.id = orders.client_id
810
+ Client.find_by_sql("SELECT * FROM clients
811
+ INNER JOIN orders ON clients.id = orders.client_id
812
812
  ORDER clients.created_at desc")
813
813
  </ruby>
814
814
 
@@ -16,7 +16,7 @@ endprologue.
16
16
 
17
17
  h3. The Object Life Cycle
18
18
 
19
- During the normal operation of a Rails application, objects may be created, updated, and destroyed. Active Record provides hooks into this <em>object life cycle</em> so that you can control your application and its data.
19
+ During the normal operation of a Rails application, objects may be created, updated, and destroyed. Active Record provides hooks into this <em>object life cycle</em> so that you can control your application and its data.
20
20
 
21
21
  Validations allow you to ensure that only valid data is stored in your database. Callbacks and observers allow you to trigger logic before or after an alteration of an object's state.
22
22
 
@@ -33,7 +33,7 @@ There are several ways to validate data before it is saved into your database, i
33
33
  * Database constraints and/or stored procedures make the validation mechanisms database-dependent and can make testing and maintenance more difficult. However, if your database is used by other applications, it may be a good idea to use some constraints at the database level. Additionally, database-level validations can safely handle some things (such as uniqueness in heavily-used tables) that can be difficult to implement otherwise.
34
34
  * Client-side validations can be useful, but are generally unreliable if used alone. If they are implemented using JavaScript, they may be bypassed if JavaScript is turned off in the user's browser. However, if combined with other techniques, client-side validation can be a convenient way to provide users with immediate feedback as they use your site.
35
35
  * Controller-level validations can be tempting to use, but often become unwieldy and difficult to test and maintain. Whenever possible, it's a good idea to "keep your controllers skinny":http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model, as it will make your application a pleasure to work with in the long run.
36
- * Model-level validations are the best way to ensure that only valid data is saved into your database. They are database agnostic, cannot be bypassed by end users, and are convenient to test and maintain. Rails makes them easy to use, provides built-in helpers for common needs, and allows you to create your own validation methods as well.
36
+ * Model-level validations are the best way to ensure that only valid data is saved into your database. They are database agnostic, cannot be bypassed by end users, and are convenient to test and maintain. Rails makes them easy to use, provides built-in helpers for common needs, and allows you to create your own validation methods as well.
37
37
 
38
38
  h4. When Does Validation Happen?
39
39
 
@@ -116,7 +116,7 @@ end
116
116
  => #<Person id: nil, name: nil>
117
117
  >> p.errors
118
118
  => {}
119
-
119
+
120
120
  >> p.valid?
121
121
  => false
122
122
  >> p.errors
@@ -126,7 +126,7 @@ end
126
126
  => #<Person id: nil, name: nil>
127
127
  >> p.errors
128
128
  => {:name=>["can't be blank"]}
129
-
129
+
130
130
  >> p.save
131
131
  => false
132
132
 
@@ -368,7 +368,7 @@ class LineItem < ActiveRecord::Base
368
368
  end
369
369
  </ruby>
370
370
 
371
- Since +false.blank?+ is true, if you want to validate the presence of a boolean field you should use +validates_inclusion_of :field_name, :in => [true, false]+.
371
+ Since +false.blank?+ is true, if you want to validate the presence of a boolean field you should use +validates_inclusion_of :field_name, :in => [true, false]+.
372
372
 
373
373
  The default error message for +validates_presence_of+ is "_can't be empty_".
374
374
 
@@ -550,9 +550,9 @@ end
550
550
 
551
551
  h3. Creating Custom Validation Methods
552
552
 
553
- When the built-in validation helpers are not enough for your needs, you can write your own validation methods.
553
+ When the built-in validation helpers are not enough for your needs, you can write your own validation methods.
554
554
 
555
- Simply create methods that verify the state of your models and add messages to the +errors+ collection when they are invalid. You must then register these methods by using one or more of the +validate+, +validate_on_create+ or +validate_on_update+ class methods, passing in the symbols for the validation methods' names.
555
+ Simply create methods that verify the state of your models and add messages to the +errors+ collection when they are invalid. You must then register these methods by using one or more of the +validate+, +validate_on_create+ or +validate_on_update+ class methods, passing in the symbols for the validation methods' names.
556
556
 
557
557
  You can pass more than one symbol for each class method and the respective validations will be run in the same order as they were registered.
558
558
 
@@ -593,7 +593,7 @@ end
593
593
 
594
594
  h3. Working with Validation Errors
595
595
 
596
- In addition to the +valid?+ and +invalid?+ methods covered earlier, Rails provides a number of methods for working with the +errors+ collection and inquiring about the validity of objects.
596
+ In addition to the +valid?+ and +invalid?+ methods covered earlier, Rails provides a number of methods for working with the +errors+ collection and inquiring about the validity of objects.
597
597
 
598
598
  The following is a list of the most commonly used methods. Please refer to the +ActiveRecord::Errors+ documentation for a list of all the available methods.
599
599
 
@@ -611,7 +611,7 @@ person = Person.new
611
611
  person.valid? # => false
612
612
  person.errors
613
613
  # => {:name => ["can't be blank", "is too short (minimum is 3 characters)"]}
614
-
614
+
615
615
  person = Person.new(:name => "John Doe")
616
616
  person.valid? # => true
617
617
  person.errors # => []
@@ -660,7 +660,7 @@ person.errors[:name]
660
660
  person.errors.full_messages
661
661
  # => ["Name cannot contain the characters !@#%*()_-+="]
662
662
  </ruby>
663
-
663
+
664
664
  Another way to do this is using +[]=+ setter
665
665
 
666
666
  <ruby>
@@ -739,7 +739,7 @@ person.errors.size # => 0
739
739
 
740
740
  h3. Displaying Validation Errors in the View
741
741
 
742
- Rails provides built-in helpers to display the error messages of your models in your view templates.
742
+ Rails provides built-in helpers to display the error messages of your models in your view templates.
743
743
 
744
744
  h4. +error_messages+ and +error_messages_for+
745
745
 
@@ -811,7 +811,7 @@ The name of the class and the id can be changed with the +:class+ and +:id+ opti
811
811
 
812
812
  h4. Customizing the Error Messages HTML
813
813
 
814
- By default, form fields with errors are displayed enclosed by a +div+ element with the +field_with_errors+ CSS class. However, it's possible to override that.
814
+ By default, form fields with errors are displayed enclosed by a +div+ element with the +field_with_errors+ CSS class. However, it's possible to override that.
815
815
 
816
816
  The way form fields with errors are treated is defined by +ActionView::Base.field_error_proc+. This is a +Proc+ that receives two parameters:
817
817
 
@@ -865,7 +865,7 @@ The macro-style class methods can also receive a block. Consider using this styl
865
865
  class User < ActiveRecord::Base
866
866
  validates_presence_of :login, :email
867
867
 
868
- before_create {|user| user.name = user.login.capitalize
868
+ before_create {|user| user.name = user.login.capitalize
869
869
  if user.name.blank?}
870
870
  end
871
871
  </ruby>
@@ -967,7 +967,7 @@ The +after_initialize+ callback is triggered every time a new object of the clas
967
967
 
968
968
  h3. Skipping Callbacks
969
969
 
970
- Just as with validations, it's also possible to skip callbacks. 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.
970
+ Just as with validations, it's also possible to skip callbacks. 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.
971
971
 
972
972
  * +decrement+
973
973
  * +decrement_counter+
@@ -982,7 +982,7 @@ Just as with validations, it's also possible to skip callbacks. These methods sh
982
982
 
983
983
  h3. Halting Execution
984
984
 
985
- As you start registering new callbacks for your models, they will be queued for execution. This queue will include all your model's validations, the registered callbacks, and the database operation to be executed.
985
+ As you start registering new callbacks for your models, they will be queued for execution. This queue will include all your model's validations, the registered callbacks, and the database operation to be executed.
986
986
 
987
987
  The whole callback chain is wrapped in a transaction. If any <em>before</em> callback method returns exactly +false+ or raises an exception the execution chain gets halted and a ROLLBACK is issued; <em>after</em> callbacks can only accomplish that by raising an exception.
988
988
 
@@ -990,11 +990,11 @@ WARNING. Raising an arbitrary exception may break code that expects +save+ and f
990
990
 
991
991
  h3. Relational Callbacks
992
992
 
993
- Callbacks work through model relationships, and can even be defined by them. Let's take an example where a user has many posts. In our example, a user's posts should be destroyed if the user is destroyed. So, we'll add an +after_destroy+ callback to the +User+ model by way of its relationship to the +Post+ model.
993
+ Callbacks work through model relationships, and can even be defined by them. Let's take an example where a user has many posts. In our example, a user's posts should be destroyed if the user is destroyed. So, we'll add an +after_destroy+ callback to the +User+ model by way of its relationship to the +Post+ model.
994
994
 
995
995
  <ruby>
996
996
  class User < ActiveRecord::Base
997
- has_many :posts, :dependent => :destroy
997
+ has_many :posts, :dependent => :destroy
998
998
  end
999
999
 
1000
1000
  class Post < ActiveRecord::Base
@@ -1069,7 +1069,7 @@ Here's an example where we create a class with an +after_destroy+ callback for a
1069
1069
  <ruby>
1070
1070
  class PictureFileCallbacks
1071
1071
  def after_destroy(picture_file)
1072
- File.delete(picture_file.filepath)
1072
+ File.delete(picture_file.filepath)
1073
1073
  if File.exists?(picture_file.filepath)
1074
1074
  end
1075
1075
  end
@@ -1088,7 +1088,7 @@ Note that we needed to instantiate a new +PictureFileCallbacks+ object, since we
1088
1088
  <ruby>
1089
1089
  class PictureFileCallbacks
1090
1090
  def self.after_destroy(picture_file)
1091
- File.delete(picture_file.filepath)
1091
+ File.delete(picture_file.filepath)
1092
1092
  if File.exists?(picture_file.filepath)
1093
1093
  end
1094
1094
  end
@@ -1144,7 +1144,7 @@ By default, Rails will simply strip "Observer" from an observer's name to find t
1144
1144
  <ruby>
1145
1145
  class MailerObserver < ActiveRecord::Observer
1146
1146
  observe :registration, :user
1147
-
1147
+
1148
1148
  def after_create(model)
1149
1149
  # code to send confirmation email...
1150
1150
  end
@@ -1,8 +1,10 @@
1
1
  h2. Active Support Core Extensions
2
2
 
3
- Active Support is the Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff. It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Rails itself.
3
+ Active Support is the Ruby on Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff.
4
4
 
5
- By referring to this guide you will learn the extensions to the Ruby core classes and modules provided by Rails.
5
+ It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Ruby on Rails itself.
6
+
7
+ By referring to this guide you will learn the extensions to the Ruby core classes and modules provided by Active Support.
6
8
 
7
9
  endprologue.
8
10
 
@@ -84,32 +86,25 @@ The following values are considered to be blank in a Rails application:
84
86
 
85
87
  WARNING: Note that numbers are not mentioned, in particular 0 and 0.0 are *not* blank.
86
88
 
87
- For example, this method from +ActionDispatch::Response+ uses +blank?+ to easily be robust to +nil+ and whitespace strings in one shot:
89
+ For example, this method from +ActionDispatch::Session::AbstractStore+ uses +blank?+ for checking whether a session key is present:
88
90
 
89
91
  <ruby>
90
- def charset
91
- charset = String(headers["Content-Type"] || headers["type"]).split(";")[1]
92
- charset.blank? ? nil : charset.strip.split("=")[1]
92
+ def ensure_session_key!
93
+ if @key.blank?
94
+ raise ArgumentError, 'A key is required...'
95
+ end
93
96
  end
94
97
  </ruby>
95
98
 
96
- That's a typical use case for +blank?+.
97
-
98
- Here, the method Rails runs to instantiate observers upon initialization has nothing to do if there are none:
99
+ The method +present?+ is equivalent to +!blank?+. This example is taken from +ActionDispatch::Http::Cache::Response+:
99
100
 
100
101
  <ruby>
101
- def instantiate_observers
102
- return if @observers.blank?
103
- # ...
102
+ def set_conditional_cache_control!
103
+ return if self["Cache-Control"].present?
104
+ ...
104
105
  end
105
106
  </ruby>
106
107
 
107
- The method +present?+ is equivalent to +!blank?+:
108
-
109
- <ruby>
110
- assert @response.body.present? # same as !@response.body.blank?
111
- </ruby>
112
-
113
108
  NOTE: Defined in +active_support/core_ext/object/blank.rb+.
114
109
 
115
110
  h4. +presence+
@@ -151,28 +146,17 @@ Active Support provides +duplicable?+ to programmatically query an object about
151
146
  false.duplicable? # => false
152
147
  </ruby>
153
148
 
154
- By definition all objects are +duplicable?+ except +nil+, +false+, +true+, symbols, numbers, and class objects.
149
+ By definition all objects are +duplicable?+ except +nil+, +false+, +true+, symbols, numbers, and class and module objects.
155
150
 
156
- WARNING. Using +duplicable?+ is discouraged because it depends on a hard-coded list. Classes have means to disallow duplication like removing +dup+ and +clone+ or raising exceptions from them, only +rescue+ can tell.
151
+ WARNING. Any class can disallow duplication removing +dup+ and +clone+ or raising exceptions from them, only +rescue+ can tell whether a given arbitrary object is duplicable. +duplicable?+ depends on the hard-coded list above, but it is much faster than +rescue+. Use it only if you know the hard-coded list is enough in your use case.
157
152
 
158
153
  NOTE: Defined in +active_support/core_ext/object/duplicable.rb+.
159
154
 
160
155
  h4. +try+
161
156
 
162
- Sometimes you want to call a method provided the receiver object is not +nil+, which is something you usually check first.
163
-
164
- For instance, note how this method of +ActiveRecord::ConnectionAdapters::AbstractAdapter+ checks if there's a +@logger+:
157
+ Sometimes you want to call a method provided the receiver object is not +nil+, which is something you usually check first. +try+ is like +Object#send+ except that it returns +nil+ if sent to +nil+.
165
158
 
166
- <ruby>
167
- def log_info(sql, name, ms)
168
- if @logger && @logger.debug?
169
- name = '%s (%.1fms)' % [name || 'SQL', ms]
170
- @logger.debug(format_log_entry(name, sql.squeeze(' ')))
171
- end
172
- end
173
- </ruby>
174
-
175
- You can shorten that using +Object#try+. This method is a synonym for +Object#send+ except that it returns +nil+ if sent to +nil+. The previous example could then be rewritten as:
159
+ For instance, in this code from +ActiveRecord::ConnectionAdapters::AbstractAdapter+ +@logger+ could be +nil+, but you save the check and write in an optimistic style:
176
160
 
177
161
  <ruby>
178
162
  def log_info(sql, name, ms)
@@ -364,7 +348,7 @@ That idiom may convey _grouping_ to the reader as well. For example, say you wan
364
348
  <ruby>
365
349
  I18n.with_options :locale => user.locale, :scope => "newsletter" do |i18n|
366
350
  subject i18n.t :subject
367
- body i18n.t :body, :user_name => user.name
351
+ body i18n.t :body, :user_name => user.name
368
352
  end
369
353
  </ruby>
370
354
 
@@ -667,129 +651,6 @@ end
667
651
 
668
652
  NOTE: Defined in +active_support/core_ext/module/attribute_accessors.rb+.
669
653
 
670
- h4. Method Delegation
671
-
672
- The class method +delegate+ offers an easy way to forward methods.
673
-
674
- For example, if +User+ has some details like the age factored out to +Profile+, it could be handy to still be able to access such attributes directly, <tt>user.age</tt>, instead of having to explicit the chain <tt>user.profile.age</tt>.
675
-
676
- That can be accomplished by hand:
677
-
678
- <ruby>
679
- class User
680
- has_one :profile
681
-
682
- def age
683
- profile.age
684
- end
685
- end
686
- </ruby>
687
-
688
- But with +delegate+ you can make that shorter and the intention even more obvious:
689
-
690
- <ruby>
691
- class User
692
- has_one :profile
693
-
694
- delegate :age, to => :profile
695
- end
696
- </ruby>
697
-
698
- The macro accepts more than one method:
699
-
700
- <ruby>
701
- class User
702
- has_one :profile
703
-
704
- delegate :age, :avatar, :twitter_username, to => :profile
705
- end
706
- </ruby>
707
-
708
- Methods can be delegated to objects returned by methods, as in the examples above, but also to instance variables, class variables, and constants. Just pass their names as symbols or strings, including the at signs in the last cases.
709
-
710
- For example, +ActionView::Base+ delegates +erb_trim_mode=+:
711
-
712
- <ruby>
713
- module ActionView
714
- class Base
715
- delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB'
716
- end
717
- end
718
- </ruby>
719
-
720
- In fact, you can delegate to any expression passed as a string. It will be evaluated in the context of the receiver. Controllers for example delegate alerts and notices to the current flash:
721
-
722
- <ruby>
723
- delegate :alert, :notice, :to => "request.flash"
724
- </ruby>
725
-
726
- If the target is +nil+ calling any delegated method will raise an exception even if +nil+ responds to such method. You can override this behavior setting the option +:allow_nil+ to true, in which case the forwarded call will simply return +nil+.
727
-
728
- If the target is a method, the name of delegated methods can also be prefixed. If the +:prefix+ option is set to (exactly) the +true+ object, the value of the +:to+ option is prefixed:
729
-
730
- <ruby>
731
- class Invoice
732
- belongs_to :customer
733
-
734
- # defines a method called customer_name
735
- delegate :name, :to => :customer, :prefix => true
736
- end
737
- </ruby>
738
-
739
- And a custom prefix can be set as well, in that case it does not matter wheter the target is a method or not:
740
-
741
- <ruby>
742
- class Account
743
- belongs_to :user
744
-
745
- # defines a method called admin_email
746
- delegate :email, :to => :user, :prefix => 'admin'
747
- end
748
- </ruby>
749
-
750
- NOTE: Defined in +active_support/core_ext/module/delegation.rb+.
751
-
752
- h4. Method Removal
753
-
754
- h5. +remove_possible_method+
755
-
756
- The method +remove_possible_method+ is like the standard +remove_method+, except it silently returns on failure:
757
-
758
- <ruby>
759
- class A; end
760
-
761
- A.class_eval do
762
- remove_method(:nonexistent) # raises NameError
763
- remove_possible_method(:nonexistent) # no problem, continue
764
- end
765
- </ruby>
766
-
767
- This may come in handy if you need to define a method that may already exist, since redefining a method issues a warning "method redefined; discarding old redefined_method_name".
768
-
769
- h5. +redefine_method(method_name, &block)+
770
-
771
- The method first removes method with given name (using +remove_possible_method+) and then defines new one.
772
-
773
- <ruby>
774
- class A; end
775
-
776
- A.class_eval do
777
- redefine_method(:foobar) do |foo|
778
- #do something here
779
- end
780
-
781
- #Code above does the same as this:
782
-
783
- method_name = :foobar
784
- remove_possible_method(method_name)
785
- define_method(method_name) do |foo|
786
- #do something here
787
- end
788
- end
789
- </ruby>
790
-
791
- NOTE: Defined in +active_support/core_ext/module/remove_method.rb+.
792
-
793
654
  h4. Parents
794
655
 
795
656
  h5. +parent+
@@ -901,7 +762,7 @@ class Counter
901
762
  end
902
763
  </ruby>
903
764
 
904
- The method receives the name of an action, and a +:with+ option with code. The code is evaluated in the context of the receiver each time the method is invoked, and it should evaluate to a +Mutex+ instance or any other object that responds to +synchronize+ and accepts a block.
765
+ The method receives the name of an action, and a +:with+ option with code. The code is evaluated in the context of the receiver each time the method is invoked, and it should evaluate to a +Mutex+ instance or any other object that responds to +synchronize+ and accepts a block.
905
766
 
906
767
  NOTE: Defined in +active_support/core_ext/module/synchronization.rb+.
907
768
 
@@ -984,6 +845,121 @@ though an anonymous module is unreachable by definition.
984
845
 
985
846
  NOTE: Defined in +active_support/core_ext/module/anonymous.rb+.
986
847
 
848
+ h4. Method Delegation
849
+
850
+ The macro +delegate+ offers an easy way to forward methods.
851
+
852
+ Let's imagine that users in some application have login information in the +User+ model but name and other data in a separate +Profile+ model:
853
+
854
+ <ruby>
855
+ class User < ActiveRecord::Base
856
+ has_one :profile
857
+ end
858
+ </ruby>
859
+
860
+ With that configuration you get a user's name via his profile, +user.profile.name+, but it could be handy to still be able to access such attribute directly:
861
+
862
+ <ruby>
863
+ class User < ActiveRecord::Base
864
+ has_one :profile
865
+
866
+ def name
867
+ profile.name
868
+ end
869
+ end
870
+ </ruby>
871
+
872
+ That is what +delegate+ does for you:
873
+
874
+ <ruby>
875
+ class User < ActiveRecord::Base
876
+ has_one :profile
877
+
878
+ delegate :name, :to => :profile
879
+ end
880
+ </ruby>
881
+
882
+ It is shorter, and the intention more obvious.
883
+
884
+ The macro accepts several methods:
885
+
886
+ <ruby>
887
+ delegate :name, :age, :address, :twitter, :to => :profile
888
+ </ruby>
889
+
890
+ When interpolated into a string, the +:to+ option should become an expression that evaluates to the object the method is delegated to. Typically a string or symbol. Such a expression is evaluated in the context of the receiver:
891
+
892
+ <ruby>
893
+ # delegates to the Rails constant
894
+ delegate :logger, :to => :Rails
895
+
896
+ # delegates to the receiver's class
897
+ delegate :table_name, :to => 'self.class'
898
+ </ruby>
899
+
900
+ WARNING: If the +:prefix+ option is +true+ this is less generic, see below.
901
+
902
+ By default, if the delegation raises +NoMethodError+ and the target is +nil+ the exception is propagated. You can ask that +nil+ is returned instead with the +:allow_nil+ option:
903
+
904
+ <ruby>
905
+ delegate :name, :to => :profile, :allow_nil => true
906
+ </ruby>
907
+
908
+ With +:allow_nil+ the call +user.name+ returns +nil+ if the user has no profile.
909
+
910
+ The option +:prefix+ adds a prefix to the name of the generated method. This may be handy for example to get a better name:
911
+
912
+ <ruby>
913
+ delegate :street, :to => :address, :prefix => true
914
+ </ruby>
915
+
916
+ The previous example generates +address_street+ rather than +street+.
917
+
918
+ WARNING: Since in this case the name of the generated method is composed of the target object and target method names, the +:to+ option must be a method name.
919
+
920
+ A custom prefix may also be configured:
921
+
922
+ <ruby>
923
+ delegate :size, :to => :attachment, :prefix => :avatar
924
+ </ruby>
925
+
926
+ In the previous example the macro generates +avatar_size+ rather than +size+.
927
+
928
+ NOTE: Defined in +active_support/core_ext/module/delegation.rb+
929
+
930
+ h4. Method Names
931
+
932
+ The builtin methods +instance_methods+ and +methods+ return method names as strings or symbols depending on the Ruby version. Active Support defines +instance_method_names+ and +method_names+ to be equivalent to them, respectively, but always getting strings back.
933
+
934
+ For example, +ActionView::Helpers::FormBuilder+ knows this array difference is going to work no matter the Ruby version:
935
+
936
+ <ruby>
937
+ self.field_helpers = (FormHelper.instance_method_names - ['form_for'])
938
+ </ruby>
939
+
940
+ NOTE: Defined in +active_support/core_ext/module/method_names.rb+
941
+
942
+ h4. Redefining Methods
943
+
944
+ There are cases where you need to define a method with +define_method+, but don't know whether a method with that name already exists. If it does, a warning is issued if they are enabled. No big deal, but not clean either.
945
+
946
+ The method +redefine_method+ prevents such a potential warning, removing the existing method before if needed. Rails uses it in a few places, for instance when it generates an association's API:
947
+
948
+ <ruby>
949
+ redefine_method("#{reflection.name}=") do |new_value|
950
+ association = association_instance_get(reflection.name)
951
+
952
+ if association.nil? || association.target != new_value
953
+ association = association_proxy_class.new(self, reflection)
954
+ end
955
+
956
+ association.replace(new_value)
957
+ association_instance_set(reflection.name, new_value.nil? ? nil : association)
958
+ end
959
+ </ruby>
960
+
961
+ NOTE: Defined in +active_support/core_ext/module/remove_method.rb+
962
+
987
963
  h3. Extensions to +Class+
988
964
 
989
965
  h4. Class Attributes
@@ -1131,25 +1107,10 @@ module ActiveRecord
1131
1107
  end
1132
1108
  </ruby>
1133
1109
 
1134
- Since values are copied when a subclass is defined, if the base class changes the attribute after that, the subclass does not see the new value. That's the point.
1110
+ Since values are copied when a subclass is defined, if the base class changes the attribute after that, the subclass does not see the new value. That's the point.
1135
1111
 
1136
1112
  NOTE: Defined in +active_support/core_ext/class/inheritable_attributes.rb+.
1137
1113
 
1138
- There's a related macro called +superclass_delegating_accessor+, however, that does not copy the value when the base class is subclassed. Instead, it delegates reading to the superclass as long as the attribute is not set via its own writer. For example, +ActionMailer::Base+ defines +delivery_method+ this way:
1139
-
1140
- <ruby>
1141
- module ActionMailer
1142
- class Base
1143
- superclass_delegating_accessor :delivery_method
1144
- self.delivery_method = :smtp
1145
- end
1146
- end
1147
- </ruby>
1148
-
1149
- If for whatever reason an application loads the definition of a mailer class and after that sets +ActionMailer::Base.delivery_method+, the mailer class will still see the new value. In addition, the mailer class is able to change the +delivery_method+ without affecting the value in the parent using its own inherited class attribute writer.
1150
-
1151
- NOTE: Defined in +active_support/core_ext/class/delegating_attributes.rb+.
1152
-
1153
1114
  h4. Subclasses & Descendants
1154
1115
 
1155
1116
  h5. +subclasses+
@@ -1178,7 +1139,7 @@ NOTE: Defined in +active_support/core_ext/class/subclasses.rb+.
1178
1139
 
1179
1140
  h5. +descendants+
1180
1141
 
1181
- The +descendants+ method returns all classes that are <tt>&lt;</tt> than its receiver:
1142
+ The +descendants+ method returns all classes that are <tt>&lt;</tt> than its receiver:
1182
1143
 
1183
1144
  <ruby>
1184
1145
  class C; end
@@ -1299,7 +1260,7 @@ Pass a +:separator+ to truncate the string at a natural break:
1299
1260
 
1300
1261
  <ruby>
1301
1262
  "Oh dear! Oh dear! I shall be late!".truncate(18)
1302
- # => "Oh dear! Oh dea..."
1263
+ # => "Oh dear! Oh dea..."
1303
1264
  "Oh dear! Oh dear! I shall be late!".truncate(18, :separator => ' ')
1304
1265
  # => "Oh dear! Oh..."
1305
1266
  </ruby>
@@ -1790,7 +1751,7 @@ The methods +to_date+, +to_time+, and +to_datetime+ are basically convenience wr
1790
1751
  <ruby>
1791
1752
  "2010-07-27".to_date # => Tue, 27 Jul 2010
1792
1753
  "2010-07-27 23:37:00".to_time # => Tue Jul 27 23:37:00 UTC 2010
1793
- "2010-07-27 23:37:00".to_datetime # => Tue, 27 Jul 2010 23:37:00 +0000
1754
+ "2010-07-27 23:37:00".to_datetime # => Tue, 27 Jul 2010 23:37:00 +0000
1794
1755
  </ruby>
1795
1756
 
1796
1757
  +to_time+ receives an optional argument +:utc+ or +:local+, to indicate which time zone you want the time in:
@@ -2229,7 +2190,27 @@ NOTE: Defined in +active_support/core_ext/array/conversions.rb+.
2229
2190
 
2230
2191
  h4. Wrapping
2231
2192
 
2232
- The class method +Array.wrap+ behaves like the function +Array()+ except that it does not try to call +to_a+ on its argument. That changes the behavior for enumerables:
2193
+ The method +Array.wrap+ wraps its argument in an array unless it is already an array (or array-like).
2194
+
2195
+ Specifically:
2196
+
2197
+ * If the argument is +nil+ an empty list is returned.
2198
+ * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
2199
+ * Otherwise, returns an array with the argument as its single element.
2200
+
2201
+ <ruby>
2202
+ Array.wrap(nil) # => []
2203
+ Array.wrap([1, 2, 3]) # => [1, 2, 3]
2204
+ Array.wrap(0) # => [0]
2205
+ </ruby>
2206
+
2207
+ This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
2208
+
2209
+ * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt> moves on to try +to_a+ if the returned value is +nil+, but <tt>Arraw.wrap</tt> returns such a +nil+ right away.
2210
+ * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt> raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
2211
+ * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
2212
+
2213
+ The last point is particularly worth comparing for some enumerables:
2233
2214
 
2234
2215
  <ruby>
2235
2216
  Array.wrap(:foo => :bar) # => [{:foo => :bar}]
@@ -2239,6 +2220,16 @@ Array.wrap("foo\nbar") # => ["foo\nbar"]
2239
2220
  Array("foo\nbar") # => ["foo\n", "bar"], in Ruby 1.8
2240
2221
  </ruby>
2241
2222
 
2223
+ There's also a related idiom that uses the splat operator:
2224
+
2225
+ <ruby>
2226
+ [*object]
2227
+ </ruby>
2228
+
2229
+ which returns +[nil]+ for +nil+, and calls to <tt>Array(object)</tt> otherwise
2230
+
2231
+ Thus, in this case the behavior is different for +nil+, and the differences with <tt>Kernel#Array</tt> explained above apply to the rest of +object+s.
2232
+
2242
2233
  NOTE: Defined in +active_support/core_ext/array/wrap.rb+.
2243
2234
 
2244
2235
  h4. Grouping
@@ -2964,11 +2955,11 @@ Note in the previous example that increments may be negative.
2964
2955
 
2965
2956
  To perform the computation the method first increments years, then months, then weeks, and finally days. This order is important towards the end of months. Say for example we are at the end of February of 2010, and we want to move one month and one day forward.
2966
2957
 
2967
- The method +advance+ advances first one month, and the one day, the result is:
2958
+ The method +advance+ advances first one month, and then one day, the result is:
2968
2959
 
2969
2960
  <ruby>
2970
- Date.new(2010, 2, 28).advance(:months => 1, :day => 1)
2971
- # => Sun, 28 Mar 2010
2961
+ Date.new(2010, 2, 28).advance(:months => 1, :days => 1)
2962
+ # => Sun, 29 Mar 2010
2972
2963
  </ruby>
2973
2964
 
2974
2965
  While if it did it the other way around the result would be different:
@@ -2994,6 +2985,26 @@ Date.new(2010, 1, 31).change(:month => 2)
2994
2985
  # => ArgumentError: invalid date
2995
2986
  </ruby>
2996
2987
 
2988
+ h5. Durations
2989
+
2990
+ Durations can be added and substracted to dates:
2991
+
2992
+ <ruby>
2993
+ d = Date.current
2994
+ # => Mon, 09 Aug 2010
2995
+ d + 1.year
2996
+ # => Tue, 09 Aug 2011
2997
+ d - 3.hours
2998
+ # => Sun, 08 Aug 2010 21:00:00 UTC +00:00
2999
+ </ruby>
3000
+
3001
+ They translate to calls to +since+ or +advance+. For example here we get the correct jump in the calendar reform:
3002
+
3003
+ <ruby>
3004
+ Date.new(1582, 10, 4) + 1.day
3005
+ # => Fri, 15 Oct 1582
3006
+ </ruby>
3007
+
2997
3008
  h5. Timestamps
2998
3009
 
2999
3010
  INFO: The following methods return a +Time+ object if possible, otherwise a +DateTime+. If set, they honor the user time zone.
@@ -3021,14 +3032,14 @@ h6. +ago+, +since+
3021
3032
  The method +ago+ receives a number of seconds as argument and returns a timestamp those many seconds ago from midnight:
3022
3033
 
3023
3034
  <ruby>
3024
- date = Date.current # => Fri, 11 Jun 2010
3035
+ date = Date.current # => Fri, 11 Jun 2010
3025
3036
  date.ago(1) # => Thu, 10 Jun 2010 23:59:59 EDT -04:00
3026
3037
  </ruby>
3027
3038
 
3028
3039
  Similarly, +since+ moves forward:
3029
3040
 
3030
3041
  <ruby>
3031
- date = Date.current # => Fri, 11 Jun 2010
3042
+ date = Date.current # => Fri, 11 Jun 2010
3032
3043
  date.since(1) # => Fri, 11 Jun 2010 00:00:01 EDT -04:00
3033
3044
  </ruby>
3034
3045
 
@@ -3038,30 +3049,30 @@ h4(#date-conversions). Conversions
3038
3049
 
3039
3050
  h3. Extensions to +DateTime+
3040
3051
 
3041
- NOTE: All the following methods are defined in +active_support/core_ext/date_time/calculations.rb+.
3042
-
3043
3052
  WARNING: +DateTime+ is not aware of DST rules and so some of these methods have edge cases when a DST change is going on. For example +seconds_since_midnight+ might not return the real amount in such a day.
3044
3053
 
3045
3054
  h4(#calculations-datetime). Calculations
3046
3055
 
3056
+ NOTE: All the following methods are defined in +active_support/core_ext/date_time/calculations.rb+.
3057
+
3047
3058
  The class +DateTime+ is a subclass of +Date+ so by loading +active_support/core_ext/date/calculations.rb+ you inherit these methods and their aliases, except that they will always return datetimes:
3048
3059
 
3049
3060
  <ruby>
3050
3061
  yesterday
3051
3062
  tomorrow
3052
- beginning_of_week
3053
- end_on_week
3063
+ beginning_of_week (monday, at_beginning_of_week)
3064
+ end_on_week (at_end_of_week)
3054
3065
  next_week
3055
3066
  months_ago
3056
3067
  months_since
3057
- beginning_of_month
3058
- end_of_month
3068
+ beginning_of_month (at_beginning_of_month)
3069
+ end_of_month (at_end_of_month)
3059
3070
  prev_month
3060
3071
  next_month
3061
- beginning_of_quarter
3062
- end_of_quarter
3063
- beginning_of_year
3064
- end_of_year
3072
+ beginning_of_quarter (at_beginning_of_quarter)
3073
+ end_of_quarter (at_end_of_quarter)
3074
+ beginning_of_year (at_beginning_of_year)
3075
+ end_of_year (at_end_of_year)
3065
3076
  years_ago
3066
3077
  years_since
3067
3078
  prev_year
@@ -3071,10 +3082,10 @@ next_year
3071
3082
  The following methods are reimplemented so you do *not* need to load +active_support/core_ext/date/calculations.rb+ for these ones:
3072
3083
 
3073
3084
  <ruby>
3074
- beginning_of_day
3085
+ beginning_of_day (midnight, at_midnight, at_beginning_of_day)
3075
3086
  end_of_day
3076
3087
  ago
3077
- since
3088
+ since (in)
3078
3089
  </ruby>
3079
3090
 
3080
3091
  On the other hand, +advance+ and +change+ are also defined and support more options, they are documented below.
@@ -3117,6 +3128,37 @@ now.utc? # => false
3117
3128
  now.utc.utc? # => true
3118
3129
  </ruby>
3119
3130
 
3131
+ h6(#datetime-advance). +advance+
3132
+
3133
+ The most generic way to jump to another datetime is +advance+. This method receives a hash with keys +:years+, +:months+, +:weeks+, +:days+, +:hours+, +:minutes+, and +:seconds+, and returns a datetime advanced as much as the present keys indicate.
3134
+
3135
+ <ruby>
3136
+ d = DateTime.current
3137
+ # => Thu, 05 Aug 2010 11:33:31 +0000
3138
+ d.advance(:years => 1, :months => 1, :days => 1, :hours => 1, :minutes => 1, :seconds => 1)
3139
+ # => Tue, 06 Sep 2011 12:34:32 +0000
3140
+ </ruby>
3141
+
3142
+ This method first computes the destination date passing +:years+, +:months+, +:weeks+, and +:days+ to +Date#advance+ documented above. After that, it adjusts the time calling +since+ with the number of seconds to advance. This order is relevant, a different ordering would give different datetimes in some edge-cases. The example in +Date#advance+ applies, and we can extend it to show order relevance related to the time bits.
3143
+
3144
+ If we first move the date bits (that have also a relative order of processing, as documented before), and then the time bits we get for example the following computation:
3145
+
3146
+ <ruby>
3147
+ d = DateTime.new(2010, 2, 28, 23, 59, 59)
3148
+ # => Sun, 28 Feb 2010 23:59:59 +0000
3149
+ d.advance(:months => 1, :seconds => 1)
3150
+ # => Mon, 29 Mar 2010 00:00:00 +0000
3151
+ </ruby>
3152
+
3153
+ but if we computed them the other way around, the result would be different:
3154
+
3155
+ <ruby>
3156
+ d.advance(:seconds => 1).advance(:months => 1)
3157
+ # => Thu, 01 Apr 2010 00:00:00 +0000
3158
+ </ruby>
3159
+
3160
+ WARNING: Since +DateTime+ is not DST-aware you can end up in a non-existing point in time with no warning or error telling you so.
3161
+
3120
3162
  h5(#datetime-changing-components). Changing Components
3121
3163
 
3122
3164
  The method +change+ allows you to get a new datetime which is the same as the receiver except for the given options, which may include +:year+, +:month+, +:day+, +:hour+, +:min+, +:sec+, +:offset+, +:start+:
@@ -3149,15 +3191,144 @@ DateTime.current.change(:month => 2, :day => 30)
3149
3191
  # => ArgumentError: invalid date
3150
3192
  </ruby>
3151
3193
 
3152
- h4(#datetime-conversions). Conversions
3194
+ h5. Durations
3195
+
3196
+ Durations can be added and substracted to datetimes:
3197
+
3198
+ <ruby>
3199
+ now = DateTime.current
3200
+ # => Mon, 09 Aug 2010 23:15:17 +0000
3201
+ now + 1.year
3202
+ # => Tue, 09 Aug 2011 23:15:17 +0000
3203
+ now - 1.week
3204
+ # => Mon, 02 Aug 2010 23:15:17 +0000
3205
+ </ruby>
3206
+
3207
+ They translate to calls to +since+ or +advance+. For example here we get the correct jump in the calendar reform:
3208
+
3209
+ <ruby>
3210
+ DateTime.new(1582, 10, 4, 23) + 1.hour
3211
+ # => Fri, 15 Oct 1582 00:00:00 +0000
3212
+ </ruby>
3153
3213
 
3154
3214
  h3. Extensions to +Time+
3155
3215
 
3156
- ...
3216
+ h4(#time-calculations). Calculations
3217
+
3218
+ NOTE: All the following methods are defined in +active_support/core_ext/date_time/calculations.rb+.
3219
+
3220
+ Active Support adds to +Time+ many of the methods available for +DateTime+:
3221
+
3222
+ <ruby>
3223
+ past?
3224
+ today?
3225
+ future?
3226
+ yesterday
3227
+ tomorrow
3228
+ seconds_since_midnight
3229
+ change
3230
+ advance
3231
+ ago
3232
+ since (in)
3233
+ beginning_of_day (midnight, at_midnight, at_beginning_of_day)
3234
+ end_of_day
3235
+ beginning_of_week (monday, at_beginning_of_week)
3236
+ end_on_week (at_end_of_week)
3237
+ next_week
3238
+ months_ago
3239
+ months_since
3240
+ beginning_of_month (at_beginning_of_month)
3241
+ end_of_month (at_end_of_month)
3242
+ prev_month
3243
+ next_month
3244
+ beginning_of_quarter (at_beginning_of_quarter)
3245
+ end_of_quarter (at_end_of_quarter)
3246
+ beginning_of_year (at_beginning_of_year)
3247
+ end_of_year (at_end_of_year)
3248
+ years_ago
3249
+ years_since
3250
+ prev_year
3251
+ next_year
3252
+ </ruby>
3253
+
3254
+ They are analogous. Please refer to their documentation above and take into account the following differences:
3255
+
3256
+ * +change+ accepts an additional +:usec+ option.
3257
+ * +Time+ understands DST, so you get correct DST calculations as in
3258
+
3259
+ <ruby>
3260
+ Time.zone_default
3261
+ # => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
3262
+
3263
+ # In Barcelona, 2010/03/28 02:00 +0100 becomes 2010/03/28 03:00 +0200 due to DST.
3264
+ t = Time.local_time(2010, 3, 28, 1, 59, 59)
3265
+ # => Sun Mar 28 01:59:59 +0100 2010
3266
+ t.advance(:seconds => 1)
3267
+ # => Sun Mar 28 03:00:00 +0200 2010
3268
+ </ruby>
3269
+
3270
+ * If +since+ or +ago+ jump to a time that can't be expressed with +Time+ a +DateTime+ object is returned instead.
3271
+
3272
+ h4. Time Constructors
3273
+
3274
+ Active Support defines +Time.current+ to be +Time.zone.now+ if there's a user time zone defined, with fallback to +Time.now+:
3275
+
3276
+ <ruby>
3277
+ Time.zone_default
3278
+ # => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
3279
+ Time.current
3280
+ # => Fri, 06 Aug 2010 17:11:58 CEST +02:00
3281
+ </ruby>
3282
+
3283
+ Analogously to +DateTime+, the predicates +past?+, and +future?+ are relative to +Time.current+.
3284
+
3285
+ Use the +local_time+ class method to create time objects honoring the user time zone:
3286
+
3287
+ <ruby>
3288
+ Time.zone_default
3289
+ # => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
3290
+ Time.local_time(2010, 8, 15)
3291
+ # => Sun Aug 15 00:00:00 +0200 2010
3292
+ </ruby>
3293
+
3294
+ The +utc_time+ class method returns a time in UTC:
3295
+
3296
+ <ruby>
3297
+ Time.zone_default
3298
+ # => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
3299
+ Time.utc_time(2010, 8, 15)
3300
+ # => Sun Aug 15 00:00:00 UTC 2010
3301
+ </ruby>
3302
+
3303
+ Both +local_time+ and +utc_time+ accept up to seven positional arguments: year, month, day, hour, min, sec, usec. Year is mandatory, month and day default to 1, and the rest default to 0.
3304
+
3305
+ If the time to be constructed lies beyond the range supported by +Time+ in the runtime platform, usecs are discarded and a +DateTime+ object is returned instead.
3306
+
3307
+ h5. Durations
3308
+
3309
+ Durations can be added and substracted to time objects:
3310
+
3311
+ <ruby>
3312
+ now = Time.current
3313
+ # => Mon, 09 Aug 2010 23:20:05 UTC +00:00
3314
+ now + 1.year
3315
+ # => Tue, 09 Aug 2011 23:21:11 UTC +00:00
3316
+ now - 1.week
3317
+ # => Mon, 02 Aug 2010 23:21:11 UTC +00:00
3318
+ </ruby>
3319
+
3320
+ They translate to calls to +since+ or +advance+. For example here we get the correct jump in the calendar reform:
3321
+
3322
+ <ruby>
3323
+ Time.utc_time(1582, 10, 3) + 5.days
3324
+ # => Mon Oct 18 00:00:00 UTC 1582
3325
+ </ruby>
3157
3326
 
3158
3327
  h3. Extensions to +Process+
3159
3328
 
3160
- ...
3329
+ h4. +daemon+
3330
+
3331
+ Ruby 1.9 provides +Process.daemon+, and Active Support defines it for previous versions. It accepts the same two arguments, whether it should chdir to the root directory (default, true), and whether it should inherit the standard file descriptors from the parent (default, false).
3161
3332
 
3162
3333
  h3. Extensions to +File+
3163
3334
 
@@ -3233,4 +3404,5 @@ h3. Changelog
3233
3404
 
3234
3405
  "Lighthouse ticket":https://rails.lighthouseapp.com/projects/16213/tickets/67
3235
3406
 
3407
+ * August 10, 2010: Starts to take shape, added to the index.
3236
3408
  * April 18, 2009: Initial version by "Xavier Noria":credits.html#fxn