railties 3.1.0.rc4 → 3.1.0.rc5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -9
- data/bin/rails +2 -0
- data/guides/assets/images/rails_welcome.png +0 -0
- data/guides/rails_guides/generator.rb +1 -1
- data/guides/rails_guides/textile_extensions.rb +18 -17
- data/guides/source/3_0_release_notes.textile +21 -21
- data/guides/source/action_controller_overview.textile +1 -1
- data/guides/source/action_mailer_basics.textile +27 -6
- data/guides/source/action_view_overview.textile +6 -6
- data/guides/source/active_record_querying.textile +77 -7
- data/guides/source/active_record_validations_callbacks.textile +78 -81
- data/guides/source/active_support_core_extensions.textile +87 -31
- data/guides/source/ajax_on_rails.textile +1 -1
- data/guides/source/api_documentation_guidelines.textile +12 -8
- data/guides/source/asset_pipeline.textile +416 -0
- data/guides/source/association_basics.textile +2 -4
- data/guides/source/caching_with_rails.textile +7 -6
- data/guides/source/command_line.textile +78 -116
- data/guides/source/configuring.textile +34 -17
- data/guides/source/contribute.textile +1 -1
- data/guides/source/contributing_to_ruby_on_rails.textile +3 -3
- data/guides/source/debugging_rails_applications.textile +2 -2
- data/guides/source/form_helpers.textile +40 -51
- data/guides/source/getting_started.textile +641 -197
- data/guides/source/initialization.textile +4 -4
- data/guides/source/layouts_and_rendering.textile +2 -2
- data/guides/source/migrations.textile +114 -32
- data/guides/source/nested_model_forms.textile +6 -6
- data/guides/source/performance_testing.textile +6 -6
- data/guides/source/plugins.textile +23 -22
- data/guides/source/rails_application_templates.textile +8 -14
- data/guides/source/routing.textile +57 -51
- data/guides/source/ruby_on_rails_guides_guidelines.textile +3 -3
- data/guides/source/security.textile +10 -10
- data/guides/source/testing.textile +1 -1
- data/lib/rails.rb +27 -1
- data/lib/rails/all.rb +1 -0
- data/lib/rails/application.rb +4 -10
- data/lib/rails/application/configuration.rb +3 -12
- data/lib/rails/application/railties.rb +1 -1
- data/lib/rails/engine.rb +53 -42
- data/lib/rails/generators.rb +1 -1
- data/lib/rails/generators/app_base.rb +36 -15
- data/lib/rails/generators/generated_attribute.rb +1 -1
- data/lib/rails/generators/js/assets/assets_generator.rb +13 -0
- data/lib/rails/generators/js/assets/templates/javascript.js +2 -0
- data/lib/rails/generators/rails/app/app_generator.rb +3 -1
- data/lib/rails/generators/rails/app/templates/Gemfile +11 -7
- data/lib/rails/generators/rails/app/templates/config/application.rb +7 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml +62 -0
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +3 -12
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml +3 -3
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +0 -3
- data/lib/rails/generators/rails/assets/assets_generator.rb +2 -9
- data/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +12 -10
- data/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +5 -2
- data/lib/rails/generators/rails/plugin_new/templates/Gemfile +6 -3
- data/lib/rails/generators/rails/plugin_new/templates/Rakefile +5 -1
- data/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt +14 -0
- data/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +5 -3
- data/lib/rails/info.rb +4 -0
- data/lib/rails/paths.rb +5 -5
- data/lib/rails/railtie.rb +4 -4
- data/lib/rails/tasks.rb +0 -1
- data/lib/rails/tasks/documentation.rake +3 -3
- data/lib/rails/tasks/engine.rake +2 -0
- data/lib/rails/tasks/framework.rake +3 -3
- data/lib/rails/tasks/tmp.rake +1 -1
- data/lib/rails/test_unit/testing.rake +2 -2
- data/lib/rails/version.rb +1 -1
- metadata +19 -33
- data/lib/rails/generators/rails/assets/templates/javascript.js.coffee +0 -3
- data/lib/rails/tasks/assets.rake +0 -21
data/CHANGELOG
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
*Rails 3.1.0 (unreleased)*
|
2
2
|
|
3
|
-
*
|
4
|
-
|
5
|
-
* Application and plugin generation run bundle install unless --skip-gemfile or --skip-bundle. [fxn]
|
3
|
+
* Make sprockets/railtie require explicit and add --skip-sprockets to app generator [José Valim]
|
6
4
|
|
7
|
-
*
|
5
|
+
* Added Rails.groups that automatically handles Rails.env and ENV["RAILS_GROUPS"] [José Valim]
|
8
6
|
|
9
|
-
|
7
|
+
* The new rake task assets:clean removes precompiled assets. [fxn]
|
10
8
|
|
11
|
-
*
|
9
|
+
* Application and plugin generation run bundle install unless --skip-gemfile or --skip-bundle. [fxn]
|
12
10
|
|
13
|
-
|
11
|
+
* Fixed database tasks for jdbc* adapters #jruby [Rashmi Yadav]
|
14
12
|
|
15
|
-
* Template generation for
|
13
|
+
* Template generation for jdbcpostgresql #jruby [Vishnu Atrai]
|
16
14
|
|
17
|
-
|
15
|
+
* Template generation for jdbcmysql and jdbcsqlite3 #jruby [Arun Agrawal]
|
18
16
|
|
19
17
|
* The -j option of the application generator accepts an arbitrary string. If passed "foo",
|
20
18
|
the gem "foo-rails" is added to the Gemfile, and the application JavaScript manifest
|
data/bin/rails
ADDED
Binary file
|
@@ -3,23 +3,24 @@ require 'active_support/core_ext/object/inclusion'
|
|
3
3
|
module RailsGuides
|
4
4
|
module TextileExtensions
|
5
5
|
def notestuff(body)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
6
|
+
# The following regexp detects special labels followed by a
|
7
|
+
# paragraph, perhaps at the end of the document.
|
8
|
+
#
|
9
|
+
# It is important that we do not eat more than one newline
|
10
|
+
# because formatting may be wrong otherwise. For example,
|
11
|
+
# if a bulleted list follows the first item is not rendered
|
12
|
+
# as a list item, but as a paragraph starting with a plain
|
13
|
+
# asterisk.
|
14
|
+
body.gsub!(/^(TIP|IMPORTANT|CAUTION|WARNING|NOTE|INFO)[.:](.*?)(\n(?=\n)|\Z)/m) do |m|
|
15
|
+
css_class = case $1
|
16
|
+
when 'CAUTION', 'IMPORTANT'
|
17
|
+
'warning'
|
18
|
+
when 'TIP'
|
19
|
+
'info'
|
20
|
+
else
|
21
|
+
$1.downcase
|
22
|
+
end
|
23
|
+
%Q(<div class="#{css_class}"><p>#{$2.strip}</p></div>)
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
@@ -61,7 +61,7 @@ h4. Upgrade Process
|
|
61
61
|
|
62
62
|
To help with the upgrade process, a plugin named "Rails Upgrade":http://github.com/jm/rails_upgrade has been created to automate part of it.
|
63
63
|
|
64
|
-
Simply install the plugin, then run +rake rails:upgrade:check+ to check your app for pieces that need to be updated (with links to information on how to update them).
|
64
|
+
Simply install the plugin, then run +rake rails:upgrade:check+ to check your app for pieces that need to be updated (with links to information on how to update them). It also offers a task to generate a +Gemfile+ based on your current +config.gem+ calls and a task to generate a new routes file from your current one. To get the plugin, simply run the following:
|
65
65
|
|
66
66
|
<shell>
|
67
67
|
$ ruby script/plugin install git://github.com/jm/rails_upgrade.git
|
@@ -69,7 +69,7 @@ $ ruby script/plugin install git://github.com/jm/rails_upgrade.git
|
|
69
69
|
|
70
70
|
You can see an example of how that works at "Rails Upgrade is now an Official Plugin":http://omgbloglol.com/post/364624593/rails-upgrade-is-now-an-official-plugin
|
71
71
|
|
72
|
-
Aside from Rails Upgrade tool, if you need more help, there are people on IRC and "rubyonrails-talk":http://groups.google.com/group/rubyonrails-talk that are probably doing the same thing, possibly hitting the same issues.
|
72
|
+
Aside from Rails Upgrade tool, if you need more help, there are people on IRC and "rubyonrails-talk":http://groups.google.com/group/rubyonrails-talk that are probably doing the same thing, possibly hitting the same issues. Be sure to blog your own experiences when upgrading so others can benefit from your knowledge!
|
73
73
|
|
74
74
|
More information - "The Path to Rails 3: Approaching the upgrade":http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade
|
75
75
|
|
@@ -113,42 +113,42 @@ Railties was updated to provide a consistent plugin API for the entire Rails fra
|
|
113
113
|
|
114
114
|
h4. All Rails core components are decoupled
|
115
115
|
|
116
|
-
With the merge of Merb and Rails, one of the big jobs was to remove the tight coupling between Rails core components.
|
116
|
+
With the merge of Merb and Rails, one of the big jobs was to remove the tight coupling between Rails core components. This has now been achieved, and all Rails core components are now using the same API that you can use for developing plugins. This means any plugin you make, or any core component replacement (like DataMapper or Sequel) can access all the functionality that the Rails core components have access to and extend and enhance at will.
|
117
117
|
|
118
118
|
More information: - "The Great Decoupling":http://yehudakatz.com/2009/07/19/rails-3-the-great-decoupling/
|
119
119
|
|
120
120
|
|
121
121
|
h4. Active Model Abstraction
|
122
122
|
|
123
|
-
Part of decoupling the core components was extracting all ties to Active Record from Action Pack.
|
123
|
+
Part of decoupling the core components was extracting all ties to Active Record from Action Pack. This has now been completed. All new ORM plugins now just need to implement Active Model interfaces to work seamlessly with Action Pack.
|
124
124
|
|
125
125
|
More information: - "Make Any Ruby Object Feel Like ActiveRecord":http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/
|
126
126
|
|
127
127
|
|
128
128
|
h4. Controller Abstraction
|
129
129
|
|
130
|
-
Another big part of decoupling the core components was creating a base superclass that is separated from the notions of HTTP in order to handle rendering of views etc.
|
130
|
+
Another big part of decoupling the core components was creating a base superclass that is separated from the notions of HTTP in order to handle rendering of views etc. This creation of +AbstractController+ allowed +ActionController+ and +ActionMailer+ to be greatly simplified with common code removed from all these libraries and put into Abstract Controller.
|
131
131
|
|
132
132
|
More Information: - "Rails Edge Architecture":http://yehudakatz.com/2009/06/11/rails-edge-architecture/
|
133
133
|
|
134
134
|
|
135
135
|
h4. Arel Integration
|
136
136
|
|
137
|
-
"Arel":http://github.com/brynary/arel (or Active Relation) has been taken on as the underpinnings of Active Record and is now required for Rails.
|
137
|
+
"Arel":http://github.com/brynary/arel (or Active Relation) has been taken on as the underpinnings of Active Record and is now required for Rails. Arel provides an SQL abstraction that simplifies out Active Record and provides the underpinnings for the relation functionality in Active Record.
|
138
138
|
|
139
139
|
More information: - "Why I wrote Arel":http://magicscalingsprinkles.wordpress.com/2010/01/28/why-i-wrote-arel/.
|
140
140
|
|
141
141
|
|
142
142
|
h4. Mail Extraction
|
143
143
|
|
144
|
-
Action Mailer ever since its beginnings has had monkey patches, pre parsers and even delivery and receiver agents, all in addition to having TMail vendored in the source tree.
|
144
|
+
Action Mailer ever since its beginnings has had monkey patches, pre parsers and even delivery and receiver agents, all in addition to having TMail vendored in the source tree. Version 3 changes that with all email message related functionality abstracted out to the "Mail":http://github.com/mikel/mail gem. This again reduces code duplication and helps create definable boundaries between Action Mailer and the email parser.
|
145
145
|
|
146
146
|
More information: - "New Action Mailer API in Rails 3":http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3
|
147
147
|
|
148
148
|
|
149
149
|
h3. Documentation
|
150
150
|
|
151
|
-
The documentation in the Rails tree is being updated with all the API changes, additionally, the "Rails Edge Guides":http://edgeguides.rubyonrails.org/ are being updated one by one to reflect the changes in Rails 3.0.
|
151
|
+
The documentation in the Rails tree is being updated with all the API changes, additionally, the "Rails Edge Guides":http://edgeguides.rubyonrails.org/ are being updated one by one to reflect the changes in Rails 3.0. The guides at "guides.rubyonrails.org":http://guides.rubyonrails.org/ however will continue to contain only the stable version of Rails (at this point, version 2.3.5, until 3.0 is released).
|
152
152
|
|
153
153
|
More Information: - "Rails Documentation Projects":http://weblog.rubyonrails.org/2009/1/15/rails-documentation-projects.
|
154
154
|
|
@@ -157,7 +157,7 @@ h3. Internationalization
|
|
157
157
|
|
158
158
|
A large amount of work has been done with I18n support in Rails 3, including the latest "I18n":http://github.com/svenfuchs/i18n gem supplying many speed improvements.
|
159
159
|
|
160
|
-
* I18n for any object - I18n behavior can be added to any object by including <tt>ActiveModel::Translation</tt> and <tt>ActiveModel::Validations</tt>.
|
160
|
+
* I18n for any object - I18n behavior can be added to any object by including <tt>ActiveModel::Translation</tt> and <tt>ActiveModel::Validations</tt>. There is also an <tt>errors.messages</tt> fallback for translations.
|
161
161
|
* Attributes can have default translations.
|
162
162
|
* Form Submit Tags automatically pull the correct status (Create or Update) depending on the object status, and so pull the correct translation.
|
163
163
|
* Labels with I18n also now work by just passing the attribute name.
|
@@ -173,7 +173,7 @@ With the decoupling of the main Rails frameworks, Railties got a huge overhaul s
|
|
173
173
|
* Anything under <tt>Rails.root/app</tt> is now added to the load path, so you can make <tt>app/observers/user_observer.rb</tt> and Rails will load it without any modifications.
|
174
174
|
* Rails 3.0 now provides a <tt>Rails.config</tt> object, which provides a central repository of all sorts of Rails wide configuration options.
|
175
175
|
|
176
|
-
Application generation has received extra flags allowing you to skip the installation of test-unit, Active Record, Prototype and Git.
|
176
|
+
Application generation has received extra flags allowing you to skip the installation of test-unit, Active Record, Prototype and Git. Also a new <tt>--dev</tt> flag has been added which sets the application up with the +Gemfile+ pointing to your Rails checkout (which is determined by the path to the +rails+ binary). See <tt>rails --help</tt> for more info.
|
177
177
|
|
178
178
|
Railties generators got a huge amount of attention in Rails 3.0, basically:
|
179
179
|
|
@@ -215,7 +215,7 @@ There have been significant internal and external changes in Action Pack.
|
|
215
215
|
|
216
216
|
h4. Abstract Controller
|
217
217
|
|
218
|
-
Abstract Controller pulls out the generic parts of Action Controller into a reusable module that any library can use to render templates, render partials, helpers, translations, logging, any part of the request response cycle.
|
218
|
+
Abstract Controller pulls out the generic parts of Action Controller into a reusable module that any library can use to render templates, render partials, helpers, translations, logging, any part of the request response cycle. This abstraction allowed <tt>ActionMailer::Base</tt> to now just inherit from +AbstractController+ and just wrap the Rails DSL onto the Mail gem.
|
219
219
|
|
220
220
|
It also provided an opportunity to clean up Action Controller, abstracting out what could to simplify the code.
|
221
221
|
|
@@ -231,7 +231,7 @@ h4. Action Controller
|
|
231
231
|
* The <tt>session_store</tt> was configured in <tt>ActionController::Base.session</tt>, and that is now moved to <tt>Rails.application.config.session_store</tt>. Defaults are set up in <tt>config/initializers/session_store.rb</tt>.
|
232
232
|
* <tt>cookies.secure</tt> allowing you to set encrypted values in cookies with <tt>cookie.secure[:key] => value</tt>.
|
233
233
|
* <tt>cookies.permanent</tt> allowing you to set permanent values in the cookie hash <tt>cookie.permanent[:key] => value</tt> that raise exceptions on signed values if verification failures.
|
234
|
-
* You can now pass <tt>:notice => 'This is a flash message'</tt> or <tt>:alert => 'Something went wrong'</tt> to the <tt>format</tt> call inside a +respond_to+ block.
|
234
|
+
* You can now pass <tt>:notice => 'This is a flash message'</tt> or <tt>:alert => 'Something went wrong'</tt> to the <tt>format</tt> call inside a +respond_to+ block. The <tt>flash[]</tt> hash still works as previously.
|
235
235
|
* <tt>respond_with</tt> method has now been added to your controllers simplifying the venerable +format+ blocks.
|
236
236
|
* <tt>ActionController::Responder</tt> added allowing you flexibility in how your responses get generated.
|
237
237
|
|
@@ -298,9 +298,9 @@ h4. Action View
|
|
298
298
|
|
299
299
|
h5. Unobtrusive JavaScript
|
300
300
|
|
301
|
-
Major re-write was done in the Action View helpers, implementing Unobtrusive JavaScript (UJS) hooks and removing the old inline AJAX commands.
|
301
|
+
Major re-write was done in the Action View helpers, implementing Unobtrusive JavaScript (UJS) hooks and removing the old inline AJAX commands. This enables Rails to use any compliant UJS driver to implement the UJS hooks in the helpers.
|
302
302
|
|
303
|
-
What this means is that all previous <tt>remote_<method></tt> helpers have been removed from Rails core and put into the "Prototype Legacy Helper":http://github.com/rails/prototype_legacy_helper.
|
303
|
+
What this means is that all previous <tt>remote_<method></tt> helpers have been removed from Rails core and put into the "Prototype Legacy Helper":http://github.com/rails/prototype_legacy_helper. To get UJS hooks into your HTML, you now pass <tt>:remote => true</tt> instead. For example:
|
304
304
|
|
305
305
|
<ruby>
|
306
306
|
form_for @post, :remote => true
|
@@ -341,12 +341,12 @@ h5. Other Changes
|
|
341
341
|
|
342
342
|
h3. Active Model
|
343
343
|
|
344
|
-
Active Model is new in Rails 3.0.
|
344
|
+
Active Model is new in Rails 3.0. It provides an abstraction layer for any ORM libraries to use to interact with Rails by implementing an Active Model interface.
|
345
345
|
|
346
346
|
|
347
347
|
h4. ORM Abstraction and Action Pack Interface
|
348
348
|
|
349
|
-
Part of decoupling the core components was extracting all ties to Active Record from Action Pack.
|
349
|
+
Part of decoupling the core components was extracting all ties to Active Record from Action Pack. This has now been completed. All new ORM plugins now just need to implement Active Model interfaces to work seamlessly with Action Pack.
|
350
350
|
|
351
351
|
More Information: - "Make Any Ruby Object Feel Like ActiveRecord":http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/
|
352
352
|
|
@@ -410,12 +410,12 @@ More Information:
|
|
410
410
|
|
411
411
|
h3. Active Record
|
412
412
|
|
413
|
-
Active Record received a lot of attention in Rails 3.0, including abstraction into Active Model, a full update to the Query interface using Arel, validation updates and many enhancements and fixes.
|
413
|
+
Active Record received a lot of attention in Rails 3.0, including abstraction into Active Model, a full update to the Query interface using Arel, validation updates and many enhancements and fixes. All of the Rails 2.x API will be usable through a compatibility layer that will be supported until version 3.1.
|
414
414
|
|
415
415
|
|
416
416
|
h4. Query Interface
|
417
417
|
|
418
|
-
Active Record, through the use of Arel, now returns relations on its core methods.
|
418
|
+
Active Record, through the use of Arel, now returns relations on its core methods. The existing API in Rails 2.3.x is still supported and will not be deprecated until Rails 3.1 and not removed until Rails 3.2, however, the new API provides the following new methods that all return relations allowing them to be chained together:
|
419
419
|
|
420
420
|
* <tt>where</tt> - provides conditions on the relation, what gets returned.
|
421
421
|
* <tt>select</tt> - choose what attributes of the models you wish to have returned from the database.
|
@@ -502,7 +502,7 @@ Deprecations:
|
|
502
502
|
|
503
503
|
h3. Active Support
|
504
504
|
|
505
|
-
A large effort was made in Active Support to make it cherry pickable, that is, you no longer have to require the entire Active Support library to get pieces of it.
|
505
|
+
A large effort was made in Active Support to make it cherry pickable, that is, you no longer have to require the entire Active Support library to get pieces of it. This allows the various core components of Rails to run slimmer.
|
506
506
|
|
507
507
|
These are the main changes in Active Support:
|
508
508
|
|
@@ -559,7 +559,7 @@ The following methods have been removed because they are no longer used in the f
|
|
559
559
|
|
560
560
|
h3. Action Mailer
|
561
561
|
|
562
|
-
Action Mailer has been given a new API with TMail being replaced out with the new "Mail":http://github.com/mikel/mail as the Email library.
|
562
|
+
Action Mailer has been given a new API with TMail being replaced out with the new "Mail":http://github.com/mikel/mail as the Email library. Action Mailer itself has been given an almost complete re-write with pretty much every line of code touched. The result is that Action Mailer now simply inherits from Abstract Controller and wraps the Mail gem in a Rails DSL. This reduces the amount of code and duplication of other libraries in Action Mailer considerably.
|
563
563
|
|
564
564
|
* All mailers are now in <tt>app/mailers</tt> by default.
|
565
565
|
* Can now send email using new API with three methods: +attachments+, +headers+ and +mail+.
|
@@ -589,7 +589,7 @@ More Information:
|
|
589
589
|
|
590
590
|
h3. Credits
|
591
591
|
|
592
|
-
See the "full list of contributors to Rails":http://contributors.rubyonrails.org/ for the many people who spent many hours making Rails 3.
|
592
|
+
See the "full list of contributors to Rails":http://contributors.rubyonrails.org/ for the many people who spent many hours making Rails 3. Kudos to all of them.
|
593
593
|
|
594
594
|
Rails 3.0 Release Notes were compiled by "Mikel Lindsaar":http://lindsaar.net.
|
595
595
|
|
@@ -802,7 +802,7 @@ class DinnerController
|
|
802
802
|
end
|
803
803
|
</ruby>
|
804
804
|
|
805
|
-
Just like the filter, you could also passing +:only+ and +:except+ to enforce the secure connection only to specific actions
|
805
|
+
Just like the filter, you could also passing +:only+ and +:except+ to enforce the secure connection only to specific actions.
|
806
806
|
|
807
807
|
<ruby>
|
808
808
|
class DinnerController
|
@@ -104,7 +104,7 @@ When you call the +mail+ method now, Action Mailer will detect the two templates
|
|
104
104
|
|
105
105
|
h5. Wire It Up So That the System Sends the Email When a User Signs Up
|
106
106
|
|
107
|
-
There are several ways to do this, some people create Rails Observers to fire off emails, others do it inside of the User Model.
|
107
|
+
There are several ways to do this, some people create Rails Observers to fire off emails, others do it inside of the User Model. However, in Rails 3, mailers are really just another way to render a view. Instead of rendering a view and sending out the HTTP protocol, they are just sending it out through the Email protocols instead. Due to this, it makes sense to just have your controller tell the mailer to send an email when a user is successfully created.
|
108
108
|
|
109
109
|
Setting this up is painfully simple.
|
110
110
|
|
@@ -276,6 +276,27 @@ Mailer views are located in the +app/views/name_of_mailer_class+ directory. The
|
|
276
276
|
|
277
277
|
To change the default mailer view for your action you do something like:
|
278
278
|
|
279
|
+
<ruby>
|
280
|
+
class UserMailer < ActionMailer::Base
|
281
|
+
default :from => "notifications@example.com"
|
282
|
+
|
283
|
+
def welcome_email(user)
|
284
|
+
@user = user
|
285
|
+
@url = "http://example.com/login"
|
286
|
+
mail(:to => user.email,
|
287
|
+
:subject => "Welcome to My Awesome Site",
|
288
|
+
:template_path => 'notifications',
|
289
|
+
:template_name => 'another')
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
end
|
294
|
+
</ruby>
|
295
|
+
|
296
|
+
In this case it will look for templates at +app/views/notifications+ with name +another+.
|
297
|
+
|
298
|
+
If you want more flexibility you can also pass a block and render specific templates or even render inline or text without using a template file:
|
299
|
+
|
279
300
|
<ruby>
|
280
301
|
class UserMailer < ActionMailer::Base
|
281
302
|
default :from => "notifications@example.com"
|
@@ -286,14 +307,14 @@ class UserMailer < ActionMailer::Base
|
|
286
307
|
mail(:to => user.email,
|
287
308
|
:subject => "Welcome to My Awesome Site") do |format|
|
288
309
|
format.html { render 'another_template' }
|
289
|
-
format.text { render '
|
310
|
+
format.text { render :text => 'Render text' }
|
290
311
|
end
|
291
312
|
end
|
292
313
|
|
293
314
|
end
|
294
315
|
</ruby>
|
295
316
|
|
296
|
-
|
317
|
+
This will render the template 'another_template.html.erb' for the HTML part and use the rendered text for the text part. The render command is the same one used inside of Action Controller, so you can use all the same options, such as <tt>:text</tt>, <tt>:inline</tt> etc.
|
297
318
|
|
298
319
|
h4. Action Mailer Layouts
|
299
320
|
|
@@ -363,7 +384,7 @@ h4. Sending Multipart Emails
|
|
363
384
|
|
364
385
|
Action Mailer will automatically send multipart emails if you have different templates for the same action. So, for our UserMailer example, if you have +welcome_email.text.erb+ and +welcome_email.html.erb+ in +app/views/user_mailer+, Action Mailer will automatically send a multipart email with the HTML and text versions setup as different parts.
|
365
386
|
|
366
|
-
The order of the parts getting inserted is determined by the <tt>:parts_order</tt> inside of the <tt>ActionMailer::Base.default</tt> method.
|
387
|
+
The order of the parts getting inserted is determined by the <tt>:parts_order</tt> inside of the <tt>ActionMailer::Base.default</tt> method. If you want to explicitly alter the order, you can either change the <tt>:parts_order</tt> or explicitly render the parts in a different order:
|
367
388
|
|
368
389
|
<ruby>
|
369
390
|
class UserMailer < ActionMailer::Base
|
@@ -401,7 +422,7 @@ The above will send a multipart email with an attachment, properly nested with t
|
|
401
422
|
|
402
423
|
h3. Receiving Emails
|
403
424
|
|
404
|
-
Receiving and parsing emails with Action Mailer can be a rather complex
|
425
|
+
Receiving and parsing emails with Action Mailer can be a rather complex endeavor. Before your email reaches your Rails app, you would have had to configure your system to somehow forward emails to your app, which needs to be listening for that. So, to receive emails in your Rails app you'll need to:
|
405
426
|
|
406
427
|
* Implement a +receive+ method in your mailer.
|
407
428
|
|
@@ -419,7 +440,7 @@ class UserMailer < ActionMailer::Base
|
|
419
440
|
)
|
420
441
|
|
421
442
|
if email.has_attachments?
|
422
|
-
|
443
|
+
email.attachments.each do |attachment|
|
423
444
|
page.attachments.create({
|
424
445
|
:file => attachment,
|
425
446
|
:description => email.subject
|
@@ -165,7 +165,7 @@ will produce
|
|
165
165
|
<em>emphasized</em>
|
166
166
|
<em><b>emph & bold</b></em>
|
167
167
|
<a href="http://rubyonrails.org">A link</a>
|
168
|
-
<target option="fast" name="compile"
|
168
|
+
<target option="fast" name="compile" />
|
169
169
|
</html>
|
170
170
|
|
171
171
|
Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
|
@@ -211,7 +211,7 @@ xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
|
|
211
211
|
end
|
212
212
|
</ruby>
|
213
213
|
|
214
|
-
h5. Template
|
214
|
+
h5. Template Caching
|
215
215
|
|
216
216
|
By default, Rails will compile each template to a method in order to render it. When you alter a template, Rails will check the file's modification time and recompile it in development mode.
|
217
217
|
|
@@ -235,7 +235,7 @@ This will render a file named +_menu.html.erb+ at that point within the view is
|
|
235
235
|
|
236
236
|
That code will pull in the partial from +app/views/shared/_menu.html.erb+.
|
237
237
|
|
238
|
-
h5. Using Partials to
|
238
|
+
h5. Using Partials to simplify Views
|
239
239
|
|
240
240
|
One way to use partials is to treat them as the equivalent of subroutines: as a way to move details out of a view so that you can grasp what's going on more easily. For example, you might have a view that looked like this:
|
241
241
|
|
@@ -615,7 +615,7 @@ atom_feed do |feed|
|
|
615
615
|
feed.title("Posts Index")
|
616
616
|
feed.updated((@posts.first.created_at))
|
617
617
|
|
618
|
-
|
618
|
+
@posts.each do |post|
|
619
619
|
feed.entry(post) do |entry|
|
620
620
|
entry.title(post.title)
|
621
621
|
entry.content(post.body, :type => 'html')
|
@@ -870,7 +870,7 @@ h4. FormHelper
|
|
870
870
|
|
871
871
|
Form helpers are designed to make working with models much easier compared to using just standard HTML elements by providing a set of methods for creating forms based on your models. This helper generates the HTML for forms, providing a method for each sort of input (e.g., text, password, select, and so on). When the form is submitted (i.e., when the user hits the submit button or form.submit is called via JavaScript), the form inputs will be bundled into the params object and passed back to the controller.
|
872
872
|
|
873
|
-
There are two types of form helpers: those that specifically work with model attributes and those that don't. This helper deals with those that work with model attributes; to see an example of form helpers that don
|
873
|
+
There are two types of form helpers: those that specifically work with model attributes and those that don't. This helper deals with those that work with model attributes; to see an example of form helpers that don't work with model attributes, check the ActionView::Helpers::FormTagHelper documentation.
|
874
874
|
|
875
875
|
The core method of this helper, form_for, gives you the ability to create a form for a model instance; for example, let's say that you have a model Person and want to create a new instance of it:
|
876
876
|
|
@@ -914,7 +914,7 @@ check_box("post", "validated")
|
|
914
914
|
|
915
915
|
h5. fields_for
|
916
916
|
|
917
|
-
Creates a scope around a specific model object like form_for, but doesn
|
917
|
+
Creates a scope around a specific model object like form_for, but doesn't create the form tags themselves. This makes fields_for suitable for specifying additional model objects in the same form:
|
918
918
|
|
919
919
|
<ruby>
|
920
920
|
<%= form_for @person, :url => { :action => "update" } do |person_form| %>
|
@@ -57,6 +57,7 @@ The methods are:
|
|
57
57
|
* +group+
|
58
58
|
* +order+
|
59
59
|
* +reorder+
|
60
|
+
* +reverse_order+
|
60
61
|
* +limit+
|
61
62
|
* +offset+
|
62
63
|
* +joins+
|
@@ -255,7 +256,7 @@ The above will yield the supplied block with +1000+ invoices every time.
|
|
255
256
|
|
256
257
|
h3. Conditions
|
257
258
|
|
258
|
-
The +
|
259
|
+
The +where+ method allows you to specify conditions to limit the records returned, representing the +WHERE+-part of the SQL statement. Conditions can either be specified as a string, array, or hash.
|
259
260
|
|
260
261
|
h4. Pure String Conditions
|
261
262
|
|
@@ -465,7 +466,7 @@ To apply a +GROUP BY+ clause to the SQL fired by the finder, you can specify the
|
|
465
466
|
For example, if you want to find a collection of the dates orders were created on:
|
466
467
|
|
467
468
|
<ruby>
|
468
|
-
Order.
|
469
|
+
Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)")
|
469
470
|
</ruby>
|
470
471
|
|
471
472
|
And this will give you a single +Order+ object for each date where there are orders in the database.
|
@@ -473,7 +474,7 @@ And this will give you a single +Order+ object for each date where there are ord
|
|
473
474
|
The SQL that would be executed would be something like this:
|
474
475
|
|
475
476
|
<sql>
|
476
|
-
SELECT
|
477
|
+
SELECT date(created_at) as ordered_date, sum(price) as total_price FROM orders GROUP BY date(created_at)
|
477
478
|
</sql>
|
478
479
|
|
479
480
|
h3. Having
|
@@ -483,16 +484,16 @@ SQL uses the +HAVING+ clause to specify conditions on the +GROUP BY+ fields. You
|
|
483
484
|
For example:
|
484
485
|
|
485
486
|
<ruby>
|
486
|
-
Order.group("date(created_at)").having("
|
487
|
+
Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)").having("sum(price) > ?", 100)
|
487
488
|
</ruby>
|
488
489
|
|
489
490
|
The SQL that would be executed would be something like this:
|
490
491
|
|
491
492
|
<sql>
|
492
|
-
SELECT
|
493
|
+
SELECT date(created_at) as ordered_date, sum(price) as total_price FROM orders GROUP BY date(created_at) HAVING sum(price) > 100
|
493
494
|
</sql>
|
494
495
|
|
495
|
-
This will return single order objects for each day, but only those that are
|
496
|
+
This will return single order objects for each day, but only those that are ordered more than $100 in a day.
|
496
497
|
|
497
498
|
h3. Overriding Conditions
|
498
499
|
|
@@ -550,6 +551,32 @@ In case the +reorder+ clause is not used, the SQL executed would be:
|
|
550
551
|
SELECT * FROM posts WHERE id = 10 ORDER BY posted_at DESC
|
551
552
|
</sql>
|
552
553
|
|
554
|
+
h4. +reverse_order+
|
555
|
+
|
556
|
+
The +reverse_order+ method reverses the ordering clause if specified.
|
557
|
+
|
558
|
+
<ruby>
|
559
|
+
Client.where("orders_count > 10").order(:name).reverse_order
|
560
|
+
</ruby>
|
561
|
+
|
562
|
+
The SQL that would be executed:
|
563
|
+
<sql>
|
564
|
+
SELECT * FROM clients WHERE orders_count > 10 ORDER BY name DESC
|
565
|
+
</sql>
|
566
|
+
|
567
|
+
If no ordering clause is specified in the query, the +reverse_order+ orders by the primary key in reverse order.
|
568
|
+
|
569
|
+
<ruby>
|
570
|
+
Client.where("orders_count > 10").reverse_order
|
571
|
+
</ruby>
|
572
|
+
|
573
|
+
The SQL that would be executed:
|
574
|
+
<sql>
|
575
|
+
SELECT * FROM clients WHERE orders_count > 10 ORDER BY clients.id DESC
|
576
|
+
</sql>
|
577
|
+
|
578
|
+
This method accepts *no* arguments.
|
579
|
+
|
553
580
|
h3. Readonly Objects
|
554
581
|
|
555
582
|
Active Record provides +readonly+ method on a relation to explicitly disallow modification or deletion of any of the returned object. Any attempt to alter or destroy a readonly record will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception.
|
@@ -938,6 +965,47 @@ Using a class method is the preferred way to accept arguments for scopes. These
|
|
938
965
|
category.posts.1_week_before(time)
|
939
966
|
</ruby>
|
940
967
|
|
968
|
+
h4. Working with scopes
|
969
|
+
|
970
|
+
Where a relational object is required, the +scoped+ method may come in handy. This will return an +ActiveRecord::Relation+ object which can have further scoping applied to it afterwards. A place where this may come in handy is on associations
|
971
|
+
|
972
|
+
<ruby>
|
973
|
+
client = Client.find_by_first_name("Ryan")
|
974
|
+
orders = client.orders.scoped
|
975
|
+
</ruby>
|
976
|
+
|
977
|
+
With this new +orders+ object, we are able to ascertain that this object can have more scopes applied to it. For instance, if we wanted to return orders only in the last 30 days at a later point.
|
978
|
+
|
979
|
+
<ruby>
|
980
|
+
orders.where("created_at > ?", 30.days.ago)
|
981
|
+
</ruby>
|
982
|
+
|
983
|
+
h4. Applying a default scope
|
984
|
+
|
985
|
+
If we wish for a scope to be applied across all queries to the model we can use the +default_scope+ method within the model itself.
|
986
|
+
|
987
|
+
<ruby>
|
988
|
+
class Client < ActiveRecord::Base
|
989
|
+
default_scope where("removed_at IS NULL")
|
990
|
+
end
|
991
|
+
</ruby>
|
992
|
+
|
993
|
+
When queries are executed on this model, the SQL query will now look something like this:
|
994
|
+
|
995
|
+
<sql>
|
996
|
+
SELECT * FROM clients WHERE removed_at IS NULL
|
997
|
+
</sql>
|
998
|
+
|
999
|
+
h4. Removing all scoping
|
1000
|
+
|
1001
|
+
If we wish to remove scoping for any reason we can use the +unscoped+ method. This is especially useful if a +default_scope+ is specified in the model and should not be applied for this particular query.
|
1002
|
+
|
1003
|
+
<ruby>
|
1004
|
+
Client.unscoped.all
|
1005
|
+
</ruby>
|
1006
|
+
|
1007
|
+
This method removes all scoping and will do a normal query on the table.
|
1008
|
+
|
941
1009
|
h3. Dynamic Finders
|
942
1010
|
|
943
1011
|
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+ and +find_all_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 +find_all_by_locked+ methods.
|
@@ -948,6 +1016,7 @@ You can specify an exclamation point (<tt>!</tt>) on the end of the dynamic find
|
|
948
1016
|
|
949
1017
|
If you want to find both by name and locked, you can chain these finders together by simply typing +and+ between the fields. For example, +Client.find_by_first_name_and_locked("Ryan", true)+.
|
950
1018
|
|
1019
|
+
WARNING: Up to and including Rails 3.1, when the number of arguments passed to a dynamic finder method is lesser than the number of fields, say <tt>Client.find_by_name_and_locked("Ryan")</tt>, the behavior is to pass +nil+ as the missing argument. This is *unintentional* and this behavior will be changed in Rails 3.2 to throw an +ArgumentError+.
|
951
1020
|
|
952
1021
|
There's another set of dynamic finders that let you find or create/initialize objects if they aren't found. These work in a similar fashion to the other finders and can be used like +find_or_create_by_first_name(params[:first_name])+. Using this will first perform a find and then create if the find returns +nil+. The SQL looks like this for +Client.find_or_create_by_first_name("Ryan")+:
|
953
1022
|
|
@@ -1119,7 +1188,8 @@ For options, please see the parent section, "Calculations":#calculations.
|
|
1119
1188
|
|
1120
1189
|
h3. Changelog
|
1121
1190
|
|
1122
|
-
*
|
1191
|
+
* June 26 2011: Added documentation for the +scoped+, +unscoped+ and +default+ methods. "Ryan Bigg":credits.html#radar
|
1192
|
+
* December 23 2010: Add documentation for the +scope+ method. "Ryan Bigg":credits.html#radar
|
1123
1193
|
* April 7, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
|
1124
1194
|
* February 3, 2010: Update to Rails 3 by "James Miller":credits.html#bensie
|
1125
1195
|
* February 7, 2009: Second version by "Pratik":credits.html#lifo
|