aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
authorGonçalo Silva <goncalossilva@gmail.com>2010-06-30 23:01:30 +0100
committerGonçalo Silva <goncalossilva@gmail.com>2010-06-30 23:01:30 +0100
commitd2c633ba0bfb7baacdee89a46d7d036d24c68817 (patch)
tree8f0974852b51597652e6ae73da26f3eb80fe878b /railties
parent92c0f17d6d2a958d3a6285b0e5408e9e0e7122e1 (diff)
parentc63cf7bf0db708fe46a929cf57649ab5a92034af (diff)
downloadrails-d2c633ba0bfb7baacdee89a46d7d036d24c68817.tar.gz
rails-d2c633ba0bfb7baacdee89a46d7d036d24c68817.tar.bz2
rails-d2c633ba0bfb7baacdee89a46d7d036d24c68817.zip
Merge branch 'master' of http://github.com/rails/rails
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG7
-rw-r--r--railties/Rakefile4
-rw-r--r--[-rwxr-xr-x]railties/guides/assets/javascripts/code_highlighter.js0
-rw-r--r--[-rwxr-xr-x]railties/guides/assets/javascripts/guides.js0
-rw-r--r--[-rwxr-xr-x]railties/guides/assets/stylesheets/print.css0
-rw-r--r--[-rwxr-xr-x]railties/guides/assets/stylesheets/reset.css0
-rw-r--r--[-rwxr-xr-x]railties/guides/assets/stylesheets/style.css0
-rw-r--r--railties/guides/source/action_controller_overview.textile19
-rw-r--r--railties/guides/source/active_record_basics.textile48
-rw-r--r--railties/guides/source/active_record_querying.textile4
-rw-r--r--railties/guides/source/active_record_validations_callbacks.textile (renamed from railties/guides/source/activerecord_validations_callbacks.textile)30
-rw-r--r--railties/guides/source/active_support_core_extensions.textile131
-rw-r--r--railties/guides/source/form_helpers.textile2
-rw-r--r--railties/guides/source/generators.textile74
-rw-r--r--railties/guides/source/getting_started.textile2
-rw-r--r--railties/guides/source/index.html.erb2
-rw-r--r--railties/guides/source/initialization.textile2
-rw-r--r--railties/guides/source/layout.html.erb2
-rw-r--r--railties/guides/source/rails_application_templates.textile4
-rw-r--r--railties/guides/source/routing.textile31
-rw-r--r--railties/guides/w3c_validator.rb36
-rw-r--r--railties/lib/rails.rb1
-rw-r--r--railties/lib/rails/application.rb42
-rw-r--r--railties/lib/rails/application/bootstrap.rb2
-rw-r--r--railties/lib/rails/application/configuration.rb6
-rw-r--r--railties/lib/rails/application/finisher.rb12
-rw-r--r--railties/lib/rails/application/routes_reloader.rb46
-rw-r--r--[-rwxr-xr-x]railties/lib/rails/commands/generate.rb0
-rw-r--r--railties/lib/rails/commands/runner.rb1
-rw-r--r--railties/lib/rails/commands/server.rb5
-rw-r--r--railties/lib/rails/console/app.rb2
-rw-r--r--railties/lib/rails/engine.rb29
-rw-r--r--railties/lib/rails/engine/configuration.rb10
-rw-r--r--railties/lib/rails/generators.rb3
-rw-r--r--railties/lib/rails/generators/actions.rb2
-rw-r--r--railties/lib/rails/generators/base.rb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb7
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb8
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb6
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb14
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/new.html.erb4
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/show.html.erb6
-rw-r--r--railties/lib/rails/generators/named_base.rb24
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/README8
-rw-r--r--[-rwxr-xr-x]railties/lib/rails/generators/rails/app/templates/Rakefile0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml60
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/routes.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js171
-rw-r--r--railties/lib/rails/generators/rails/model/USAGE2
-rw-r--r--railties/lib/rails/generators/rails/resource/resource_generator.rb18
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb58
-rw-r--r--railties/lib/rails/generators/resource_helpers.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/model/model_generator.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb1
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb28
-rw-r--r--railties/lib/rails/initializable.rb19
-rw-r--r--railties/lib/rails/log_subscriber.rb115
-rw-r--r--railties/lib/rails/log_subscriber/test_helper.rb97
-rw-r--r--railties/lib/rails/paths.rb51
-rw-r--r--railties/lib/rails/plugin.rb16
-rw-r--r--railties/lib/rails/rack/logger.rb24
-rw-r--r--railties/lib/rails/railtie.rb34
-rw-r--r--railties/lib/rails/webrick_server.rb156
-rw-r--r--railties/test/abstract_unit.rb2
-rw-r--r--railties/test/application/initializers/frameworks_test.rb10
-rw-r--r--railties/test/application/initializers/i18n_test.rb133
-rw-r--r--railties/test/application/initializers/load_path_test.rb2
-rw-r--r--railties/test/application/loading_test.rb86
-rw-r--r--railties/test/application/middleware_test.rb11
-rw-r--r--railties/test/application/model_initialization_test.rb33
-rw-r--r--railties/test/application/rake_test.rb2
-rw-r--r--railties/test/application/runner_test.rb49
-rw-r--r--railties/test/application/url_generation_test.rb1
-rw-r--r--railties/test/generators/actions_test.rb6
-rw-r--r--railties/test/generators/migration_generator_test.rb15
-rw-r--r--railties/test/generators/named_base_test.rb10
-rw-r--r--railties/test/generators/resource_generator_test.rb8
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb14
-rw-r--r--railties/test/generators/scaffold_generator_test.rb106
-rw-r--r--railties/test/initializable_test.rb39
-rw-r--r--railties/test/isolation/abstract_unit.rb3
-rw-r--r--railties/test/log_subscriber_test.rb123
-rw-r--r--railties/test/paths_test.rb56
-rw-r--r--railties/test/railties/engine_test.rb6
-rw-r--r--railties/test/railties/i18n_railtie_test.rb89
-rw-r--r--railties/test/railties/plugin_test.rb30
-rw-r--r--railties/test/railties/railtie_test.rb9
-rw-r--r--railties/test/railties/shared_tests.rb45
98 files changed, 1147 insertions, 1263 deletions
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index c33a4d11dd..8e2bac7f00 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -1,6 +1,13 @@
*Rails 3.0.0 [Release Candidate] (unreleased)*
+* Rails no longer autoload code in lib for application. You need to explicitly require it. [José Valim]
+
+* Rails::LogSubscriber was renamed to ActiveSupport::LogSubscriber [José Valim]
+
+* config.load_(once_)paths in config/application.rb got renamed to config.autoload_(once_)paths. [fxn]
+
* Abort generation/booting on Ruby 1.9.1. [fxn]
+
* Made the rails command work even when you're in a subdirectory [Chad Fowler]
diff --git a/railties/Rakefile b/railties/Rakefile
index bf19961b59..ddc872e18b 100644
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -18,11 +18,11 @@ task :test => 'test:isolated'
namespace :test do
task :isolated do
dir = ENV["TEST_DIR"] || "**"
- Dir["test/#{dir}/*_test.rb"].all? do |file|
+ Dir["test/#{dir}/*_test.rb"].each do |file|
next true if file.include?("fixtures")
ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
system(ruby, '-Itest', "-I#{File.dirname(__FILE__)}/../activesupport/lib", file)
- end or raise "Failures"
+ end
end
end
diff --git a/railties/guides/assets/javascripts/code_highlighter.js b/railties/guides/assets/javascripts/code_highlighter.js
index ce983dad52..ce983dad52 100755..100644
--- a/railties/guides/assets/javascripts/code_highlighter.js
+++ b/railties/guides/assets/javascripts/code_highlighter.js
diff --git a/railties/guides/assets/javascripts/guides.js b/railties/guides/assets/javascripts/guides.js
index c4e4d459ea..c4e4d459ea 100755..100644
--- a/railties/guides/assets/javascripts/guides.js
+++ b/railties/guides/assets/javascripts/guides.js
diff --git a/railties/guides/assets/stylesheets/print.css b/railties/guides/assets/stylesheets/print.css
index 628da105d4..628da105d4 100755..100644
--- a/railties/guides/assets/stylesheets/print.css
+++ b/railties/guides/assets/stylesheets/print.css
diff --git a/railties/guides/assets/stylesheets/reset.css b/railties/guides/assets/stylesheets/reset.css
index cb14fbcc55..cb14fbcc55 100755..100644
--- a/railties/guides/assets/stylesheets/reset.css
+++ b/railties/guides/assets/stylesheets/reset.css
diff --git a/railties/guides/assets/stylesheets/style.css b/railties/guides/assets/stylesheets/style.css
index 89b2ab885a..89b2ab885a 100755..100644
--- a/railties/guides/assets/stylesheets/style.css
+++ b/railties/guides/assets/stylesheets/style.css
diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile
index 9d8426b5de..038ca903c1 100644
--- a/railties/guides/source/action_controller_overview.textile
+++ b/railties/guides/source/action_controller_overview.textile
@@ -338,6 +338,25 @@ end
Note that while for session values you set the key to +nil+, to delete a cookie value you should use +cookies.delete(:key)+.
+h3. Rendering xml and json data
+
+ActionController makes it extremely easy to render +xml+ or +json+ data. If you generate a controller using scaffold then your controller would look something like this.
+
+<ruby>
+class UsersController < ApplicationController
+ def index
+ @users = User.all
+ respond_to do |format|
+ format.html # index.html.erb
+ format.xml { render :xml => @users}
+ end
+ end
+end
+</ruby>
+
+Notice that in the above case code is <tt>render :xml => @users</tt> and not <tt>render :xml => @users.to_xml</tt>. That is because if the input is not string then rails automatically invokes +to_xml+ .
+
+
h3. Filters
Filters are methods that are run before, after or "around" a controller action.
diff --git a/railties/guides/source/active_record_basics.textile b/railties/guides/source/active_record_basics.textile
index d81e461e63..e6ef2cdd20 100644
--- a/railties/guides/source/active_record_basics.textile
+++ b/railties/guides/source/active_record_basics.textile
@@ -32,16 +32,16 @@ Active Record gives us several mechanisms, the most important being the ability
* Validate models before they get persisted to the database
* Perform database operations in an object-oriented fashion.
-h3. Convention over Configuration in ActiveRecord
+h3. Convention over Configuration in Active Record
-When writing applications using other programming languages or frameworks, it may be necessary to write a lot of configuration code. This is particularly true for ORM frameworks in general. However, if you follow the conventions adopted by Rails, you'll need to write very little configuration (in some case no configuration at all) when creating ActiveRecord models. The idea is that if you configure your applications in the very same way most of the times then this should be the default way. In this cases, explicit configuration would be needed only in those cases where you can't follow the conventions for any reason.
+When writing applications using other programming languages or frameworks, it may be necessary to write a lot of configuration code. This is particularly true for ORM frameworks in general. However, if you follow the conventions adopted by Rails, you'll need to write very little configuration (in some case no configuration at all) when creating Active Record models. The idea is that if you configure your applications in the very same way most of the times then this should be the default way. In this cases, explicit configuration would be needed only in those cases where you can't follow the conventions for any reason.
h4. Naming Conventions
-By default, ActiveRecord uses some naming conventions to find out how the mapping between models and database tables should be created. Rails will pluralize your class names to find the respective database table. So, for a class +Book+, you should have a database table called *books*. The Rails pluralization mechanisms are very powerful, being capable to pluralize (and singularize) both regular and irregular words. When using class names composed of two or more words, the model class name should follow the Ruby conventions, using the camelCase form, while the table name must contain the words separated by underscores. Examples:
+By default, Active Record uses some naming conventions to find out how the mapping between models and database tables should be created. Rails will pluralize your class names to find the respective database table. So, for a class +Book+, you should have a database table called *books*. The Rails pluralization mechanisms are very powerful, being capable to pluralize (and singularize) both regular and irregular words. When using class names composed of two or more words, the model class name should follow the Ruby conventions, using the camelCase form, while the table name must contain the words separated by underscores. Examples:
-* Database Table - Plural with underscores separating words i.e. (book_clubs)
-* Model Class - Singular with the first letter of each word capitalized i.e. (BookClub)
+* Database Table - Plural with underscores separating words (e.g., book_clubs)
+* Model Class - Singular with the first letter of each word capitalized (e.g., BookClub)
|_.Model / Class |_.Table / Schema |
|Post |posts|
@@ -53,30 +53,32 @@ By default, ActiveRecord uses some naming conventions to find out how the mappin
h4. Schema Conventions
-ActiveRecord uses naming conventions for the columns in database tables, depending on the purpose of these columns.
+Active Record uses naming conventions for the columns in database tables, depending on the purpose of these columns.
-* *Foreign keys* - These fields should be named following the pattern table_id i.e. (item_id, order_id). These are the fields that ActiveRecord will look for when you create associations between your models.
-* *Primary keys* - By default, ActiveRecord will use an integer column named "id" as the table's primary key. When using "Rails Migrations":migrations.html to create your tables, this column will be automatically created.
+* *Foreign keys* - These fields should be named following the pattern table_id (e.g., item_id, order_id). These are the fields that Active Record will look for when you create associations between your models.
+* *Primary keys* - By default, Active Record will use an integer column named "id" as the table's primary key. When using "Rails Migrations":migrations.html to create your tables, this column will be automatically created.
-There are also some optional column names that will create additional features to ActiveRecord instances:
+There are also some optional column names that will create additional features to Active Record instances:
-* *created_at / created_on* - ActiveRecord will store the current date and time to this field when creating the record.
-* *updated_at / updated_on* - ActiveRecord will store the current date and times to this field when updating the record.
+* *created_at* - Automatically gets set to the current date and time when the record is first created.
+* *created_on* - Automatically gets set to the current date when the record is first created.
+* *updated_at* - Automatically gets set to the current date and time whenever the record is updated.
+* *updated_on* - Automatically gets set to the current date whenever the record is updated.
* *lock_version* - Adds "optimistic locking":http://api.rubyonrails.com/classes/ActiveRecord/Locking.html to a model.
* *type* - Specifies that the model uses "Single Table Inheritance":http://api.rubyonrails.com/classes/ActiveRecord/Base.html
* *(table_name)_count* - Used to cache the number of belonging objects on associations. For example, a +comments_count+ column in a +Post+ class that has many instances of +Comment+ will cache the number of existent comments for each post.
-NOTE: While these column names are optional they are in fact reserved by ActiveRecord. Steer clear of reserved keywords unless you want the extra functionality. For example, "type" is a reserved keyword used to designate a table using Single Table Inheritance. If you are not using STI, try an analogous keyword like "context", that may still accurately describe the data you are modeling.
+NOTE: While these column names are optional they are in fact reserved by Active Record. Steer clear of reserved keywords unless you want the extra functionality. For example, "type" is a reserved keyword used to designate a table using Single Table Inheritance. If you are not using STI, try an analogous keyword like "context", that may still accurately describe the data you are modeling.
-h3. Creating ActiveRecord Models
+h3. Creating Active Record Models
-It's very easy to create ActiveRecord models. All you have to do is to subclass the ActiveRecord::Base class and you're good to go:
+It's very easy to create Active Record models. All you have to do is to subclass the +ActiveRecord::Base+ class and you're good to go:
<ruby>
class Product < ActiveRecord::Base; end
</ruby>
-This will create a +Product+ model, mapped to a *products* table at the database. By doing this you'll also have the ability to map the columns of each row in that table with the attributes of the instances of your model. So, suppose that the *products* table was created using a SQL sentence like:
+This will create a +Product+ model, mapped to a *products* table at the database. By doing this you'll also have the ability to map the columns of each row in that table with the attributes of the instances of your model. So, suppose that the *products* table was created using an SQL sentence like:
<sql>
CREATE TABLE products (
@@ -99,12 +101,15 @@ h3. Overriding the Naming Conventions
What if you need to follow a different naming convention or need to use your Rails application with a legacy database? No problem, you can easily override the default conventions.
You can use the +ActiveRecord::Base.set_table_name+ method to specify the table name that should be used:
+
<ruby>
class Product < ActiveRecord::Base
set_table_name "PRODUCT"
end
</ruby>
+
If you do so, you will have to define manually the class name that is hosting the fixtures (class_name.yml) using the +set_fixture_class+ method in your test definition:
+
<ruby>
class FunnyJoke < ActiveSupport::TestCase
set_fixture_class :funny_jokes => 'Joke'
@@ -113,7 +118,8 @@ class FunnyJoke < ActiveSupport::TestCase
end
</ruby>
-It's also possible to override the column that should be used as the table's primary key. Use the +ActiveRecord::Base.set_primary_key+ method for that:
+It's also possible to override the column that should be used as the table's primary key using the +ActiveRecord::Base.set_primary_key+ method:
+
<ruby>
class Product < ActiveRecord::Base
set_primary_key "product_id"
@@ -122,7 +128,7 @@ end
h3. Reading and Writing Data
-CRUD is an acronym for the four verbs we use to operate on data: Create, Read, Update, Delete. Active Record automatically creates methods to allow an application to read and manipulate data stored within its tables.
+CRUD is an acronym for the four verbs we use to operate on data: *C*reate, *R*ead, *U*pdate and *D*elete. Active Record automatically creates methods to allow an application to read and manipulate data stored within its tables.
h4. Create
@@ -155,7 +161,7 @@ Finally, passing a block to either create or new will return a new User object:
h4. Read
-ActiveRecord provides a rich API for accessing data within a database. Below are a few examples of different data access methods provided by ActiveRecord.
+Active Record provides a rich API for accessing data within a database. Below are a few examples of different data access methods provided by Active Record.
<ruby>
# return all records
@@ -163,7 +169,7 @@ ActiveRecord provides a rich API for accessing data within a database. Below are
</ruby>
<ruby>
- # return first record
+ # return the first record
user = User.first
</ruby>
@@ -201,11 +207,11 @@ Likewise, once retrieved an Active Record object can be destroyed which removes
h3. Validations
-Active Record allows you to validate the state of a model before it gets written into the database. There are several methods that you can use to check your models and validate that an attribute value is not empty, is unique and not already in the database, follows a specific format and many more. You can learn more about validations in the "Active Record Validations and Callbacks guide":activerecord_validations_callbacks.html#validations-overview.
+Active Record allows you to validate the state of a model before it gets written into the database. There are several methods that you can use to check your models and validate that an attribute value is not empty, is unique and not already in the database, follows a specific format and many more. You can learn more about validations in the "Active Record Validations and Callbacks guide":active_record_validations_callbacks.html#validations-overview.
h3. Callbacks
-Active Record callbacks allow you to attach code to certain events in the life-cycle of your models. This enables you to add behavior to your models by transparently executing code when those events occur, like when you create a new record, update it, destroy it and so on. You can learn more about callbacks in the "Active Record Validations and Callbacks guide":activerecord_validations_callbacks.html#callbacks-overview.
+Active Record callbacks allow you to attach code to certain events in the life-cycle of your models. This enables you to add behavior to your models by transparently executing code when those events occur, like when you create a new record, update it, destroy it and so on. You can learn more about callbacks in the "Active Record Validations and Callbacks guide":active_record_validations_callbacks.html#callbacks-overview.
h3. Migrations
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile
index 73f3ebafbe..f5e70aef41 100644
--- a/railties/guides/source/active_record_querying.textile
+++ b/railties/guides/source/active_record_querying.textile
@@ -51,7 +51,7 @@ Active Record will perform queries on the database for you and is compatible wit
h3. Retrieving Objects from the Database
-To retrieve objects from the database, Active Record provides several finder methods. These methods allows you to pass arguments into it to perform certain queries on your database without the need of writing raw SQL.
+To retrieve objects from the database, Active Record provides several finder methods. Each finder method allows you to pass arguments into it to perform certain queries on your database without writing raw SQL.
The methods are:
* +where+
@@ -66,7 +66,7 @@ The methods are:
* +readonly+
* +from+
-All of these methods return a Relation
+All of the above methods return an instance of <tt>ActiveRecord::Relation</tt>.
Primary operation of <tt>Model.find(options)</tt> can be summarized as:
diff --git a/railties/guides/source/activerecord_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile
index 1f9bc1279a..cfd4ae55cc 100644
--- a/railties/guides/source/activerecord_validations_callbacks.textile
+++ b/railties/guides/source/active_record_validations_callbacks.textile
@@ -16,7 +16,7 @@ endprologue.
h3. The Object Lifecycle
-During the normal operation of a Rails application objects may be created, updated, and destroyed. Active Record provides hooks into this <em>object lifecycle</em> so that you can control your application and its data.
+During the normal operation of a Rails application, objects may be created, updated, and destroyed. Active Record provides hooks into this <em>object lifecycle</em> so that you can control your application and its data.
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.
@@ -71,7 +71,7 @@ The following methods trigger validations, and will save the object to the datab
* +update_attributes+
* +update_attributes!+
-The bang versions (e.g. +save!+) raise an exception if the record is invalid. The non-bang versions don't: +save+ and +update_attributes+ return +false+, +create+ and +update+ just return the object/s.
+The bang versions (e.g. +save!+) raise an exception if the record is invalid. The non-bang versions don't: +save+ and +update_attributes+ return +false+, +create+ and +update+ just return the objects.
h4. Skipping Validations
@@ -240,9 +240,9 @@ class Account < ActiveRecord::Base
end
</ruby>
-The +validates_exclusion_of+ helper has an option +:in+ that receives the set of values that will not be accepted for the validated attributes. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. This example uses the +:message+ option to show how you can include the attribute's value.
+The +validates_exclusion_of+ helper has an option +:in+ that receives the set of values that will not be accepted for the validated attributes. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. This example uses the +:message+ option to show how you can include the attribute's value.
-The default error message for +validates_exclusion_of+ is "_is reserved_".
+The default error message for +validates_exclusion_of+ is "_is reserved_".
h4. +validates_format_of+
@@ -270,7 +270,7 @@ end
The +validates_inclusion_of+ helper has an option +:in+ that receives the set of values that will be accepted. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. The previous example uses the +:message+ option to show how you can include the attribute's value.
-The default error message for +validates_inclusion_of+ is "_is not included in the list_".
+The default error message for +validates_inclusion_of+ is "_is not included in the list_".
h4. +validates_length_of+
@@ -343,7 +343,7 @@ Besides +:only_integer+, the +validates_numericality_of+ helper also accepts the
* +:greater_than_or_equal_to+ - Specifies the value must be greater than or equal to the supplied value. The default error message for this option is "_must be greater than or equal to %{count}_".
* +:equal_to+ - Specifies the value must be equal to the supplied value. The default error message for this option is "_must be equal to %{count}_".
* +:less_than+ - Specifies the value must be less than the supplied value. The default error message for this option is "_must be less than %{count}_".
-* +:less_than_or_equal_to+ - Specifies the value must be less than or equal the supplied value. The default error message for this option is "_must be less or equal to %{count}_".
+* +:less_than_or_equal_to+ - Specifies the value must be less than or equal the supplied value. The default error message for this option is "_must be less than or equal to %{count}_".
* +:odd+ - Specifies the value must be an odd number if set to true. The default error message for this option is "_must be odd_".
* +:even+ - Specifies the value must be an even number if set to true. The default error message for this option is "_must be even_".
@@ -374,7 +374,7 @@ The default error message for +validates_presence_of+ is "_can't be empty_".
h4. +validates_uniqueness_of+
-This helper validates that the attribute's value is unique right before the object gets saved. It does not create a uniqueness constraint in the database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create an unique index in your database.
+This helper validates that the attribute's value is unique right before the object gets saved. It does not create a uniqueness constraint in the database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create a unique index in your database.
<ruby>
class Account < ActiveRecord::Base
@@ -423,14 +423,14 @@ class GoodnessValidator < ActiveRecord::Validator
end
</ruby>
-The +validates_with+ helper takes a class, or a list of classes to use for validation. There is no default error message for +validates_with+. You must manually add errors to the record's errors collection in the validator class.
+The +validates_with+ helper takes a class, or a list of classes to use for validation. There is no default error message for +validates_with+. You must manually add errors to the record's errors collection in the validator class.
The validator class has two attributes by default:
* +record+ - the record to be validated
* +options+ - the extra options that were passed to +validates_with+
-Like all other validations, +validates_with+ takes the +:if+, +:unless+ and +:on+ options. If you pass any other options, it will send those options to the validator class as +options+:
+Like all other validations, +validates_with+ takes the +:if+, +:unless+ and +:on+ options. If you pass any other options, it will send those options to the validator class as +options+:
<ruby>
class Person < ActiveRecord::Base
@@ -494,7 +494,7 @@ As you've already seen, the +:message+ option lets you specify the message that
h4. +:on+
-The +:on+ option lets you specify when the validation should happen. The default behavior for all the built-in validation helpers is to be ran on save (both when you're creating a new record and when you're updating it). If you want to change it, you can use +:on => :create+ to run the validation only when a new record is created or +:on => :update+ to run the validation only when a record is updated.
+The +:on+ option lets you specify when the validation should happen. The default behavior for all the built-in validation helpers is to be run on save (both when you're creating a new record and when you're updating it). If you want to change it, you can use +:on => :create+ to run the validation only when a new record is created or +:on => :update+ to run the validation only when a record is updated.
<ruby>
class Person < ActiveRecord::Base
@@ -573,7 +573,7 @@ class Invoice < ActiveRecord::Base
end
</ruby>
-You can even create your own validation helpers and reuse them in several different models. For example, an application that manages surveys may find useful to express that a certain field corresponds to a set of choices:
+You can even create your own validation helpers and reuse them in several different models. For example, an application that manages surveys may find it useful to express that a certain field corresponds to a set of choices:
<ruby>
ActiveRecord::Base.class_eval do
@@ -599,7 +599,7 @@ The following is a list of the most commonly used methods. Please refer to the +
h4(#working_with_validation_errors-errors). +errors+
-Returns an OrderedHash with all errors. Each key is the attribute name and value is an array of strings with all errors.
+Returns an OrderedHash with all errors. Each key is the attribute name and the value is an array of strings with all errors.
<ruby>
class Person < ActiveRecord::Base
@@ -619,7 +619,7 @@ person.errors # => []
h4(#working_with_validation_errors-errors-2). +errors[]+
-+errors[]+ is used when you want to check the error messages for a specific attribute. It returns an array of strings with all error messages for the given attribute, each string with one error message. If there are no errors related to the attribute returns an empty array.
++errors[]+ is used when you want to check the error messages for a specific attribute. It returns an array of strings with all error messages for the given attribute, each string with one error message. If there are no errors related to the attribute, it returns an empty array.
<ruby>
class Person < ActiveRecord::Base
@@ -681,7 +681,7 @@ Another way to do this is using +[]=+ setter
h4. +errors[:base]+
-You can add errors messages that are related to the object's state as a whole, instead of being related to a specific attribute. You can use this method when you want to say that the object is invalid, no matter the values of its attributes. Since +errors[:base]+ is an array, you can simply add a string to the array and uses it as the error message.
+You can add error messages that are related to the object's state as a whole, instead of being related to a specific attribute. You can use this method when you want to say that the object is invalid, no matter the values of its attributes. Since +errors[:base]+ is an array, you can simply add a string to the array and uses it as the error message.
<ruby>
class Person < ActiveRecord::Base
@@ -789,7 +789,7 @@ Both the +form.error_messages+ and the +error_messages_for+ helpers accept optio
:header_tag => :h3 %>
</erb>
-Which results in the following content
+Which results in the following content:
!images/customized_error_messages.png(Customized error messages)!
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index 1c17609b0a..844b9428bd 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -24,7 +24,7 @@ h5. Cherry-picking a Definition
The most lightweight way to get +blank?+ is to cherry-pick the file that defines it.
-For every single method defined as a core extension this guide has a note that says where is such a method defined. In the case of +blank?+ the note reads:
+For every single method defined as a core extension this guide has a note that says where such a method is defined. In the case of +blank?+ the note reads:
NOTE: Defined in +active_support/core_ext/object/blank.rb+.
@@ -124,7 +124,7 @@ NOTE: Defined in +active_support/core_ext/object/blank.rb+.
h4. +duplicable?+
-A few fundamental objects in Ruby are singletons. For example, in the whole live of a program the integer 1 refers always to the same instance:
+A few fundamental objects in Ruby are singletons. For example, in the whole life of a program the integer 1 refers always to the same instance:
<ruby>
1.object_id # => 3
@@ -159,7 +159,7 @@ NOTE: Defined in +active_support/core_ext/object/duplicable.rb+.
h4. +returning+
-The method +returning+ yields its argument to a block and returns it. You tipically use it with a mutable object that gets modified in the block:
+The method +returning+ yields its argument to a block and returns it. You typically use it with a mutable object that gets modified in the block:
<ruby>
def html_options_for_form(url_for_options, options, *parameters_for_url)
@@ -187,7 +187,7 @@ def log_info(sql, name, ms)
end
</ruby>
-You can shorten that using +Object#try+. This method is a synonim for +Object#send+ except that it returns +nil+ if sent to +nil+. The previous example could then be rewritten as:
+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:
<ruby>
def log_info(sql, name, ms)
@@ -209,8 +209,7 @@ String.singleton_class # => #<Class:String>
String.new.singleton_class # => #<Class:#<String:0x17a1d1c>>
</ruby>
-WARNING: Fixnums and symbols have no singleton classes, +singleton_class+
-raises +TypeError+ on them. Moreover, the singleton classes of +nil+, +true+, and +false+, are +NilClass+, +TrueClass+, and +FalseClass+, respectively.
+WARNING: Fixnums and symbols have no singleton classes, +singleton_class+ raises +TypeError+ on them. Moreover, the singleton classes of +nil+, +true+, and +false+, are +NilClass+, +TrueClass+, and +FalseClass+, respectively.
NOTE: Defined in +active_support/core_ext/kernel/singleton_class.rb+.
@@ -256,7 +255,7 @@ NOTE: Defined in +active_support/core_ext/object/acts_like.rb+.
h4. +to_param+
-All objects in Rails respond to the method +to_param+, which is meant to return something that represents them as values in a query string, or as a URL fragments.
+All objects in Rails respond to the method +to_param+, which is meant to return something that represents them as values in a query string, or as URL fragments.
By default +to_param+ just calls +to_s+:
@@ -294,7 +293,7 @@ we get:
user_path(@user) # => "/users/357-john-smith"
</ruby>
-WARNING. Controllers need to be aware of any redifinition of +to_param+ because when a request like that comes in "357-john-smith" is the value of +params[:id]+.
+WARNING. Controllers need to be aware of any redefinition of +to_param+ because when a request like that comes in "357-john-smith" is the value of +params[:id]+.
NOTE: Defined in +active_support/core_ext/object/to_param.rb+.
@@ -332,7 +331,7 @@ Arrays return the result of applying +to_query+ to each element with <tt>_key_[]
# => "sample%5B%5D=3.4&sample%5B%5D=-45.6"
</ruby>
-Hashes also respond to +to_query+ but with a different signature. If no argument is passed a call generates a sorted series of key/value assigments calling +to_query(key)+ on its values. Then it joins the result with "&":
+Hashes also respond to +to_query+ but with a different signature. If no argument is passed a call generates a sorted series of key/value assignments calling +to_query(key)+ on its values. Then it joins the result with "&":
<ruby>
{:c => 3, :b => 2, :a => 1}.to_query # => "a=1&b=2&c=3"
@@ -656,9 +655,9 @@ h5. Internal Attributes
When you are defining an attribute in a class that is meant to be subclassed name collisions are a risk. That's remarkably important for libraries.
-Active Support defines the macros +attr_internal_reader+, +attr_internal_writer+, and +attr_internal_accessor+. They behave like their Ruby builtin +attr_*+ counterparts, except they name the unerlying instace variable in a way that makes collisions less likely.
+Active Support defines the macros +attr_internal_reader+, +attr_internal_writer+, and +attr_internal_accessor+. They behave like their Ruby builtin +attr_*+ counterparts, except they name the underlying instance variable in a way that makes collisions less likely.
-The macro +attr_internal+ is a synonim for +attr_internal_accessor+:
+The macro +attr_internal+ is a synonym for +attr_internal_accessor+:
<ruby>
# library
@@ -721,7 +720,7 @@ h4. Method Delegation
The class method +delegate+ offers an easy way to forward methods.
-For example, if +User+ has some details like the age factored out to +Profile+, it could be handy to still be able to acces such attribute directly, <tt>user.age</tt>, instead of having to explicit the chain <tt>user.profile.age</tt>.
+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>.
That can be accomplished by hand:
@@ -935,7 +934,7 @@ NOTE: Defined in +active_support/core_ext/module/synchronization.rb+.
h4. Reachable
-A named module is reachable if it is stored in its correspoding constant. It means you can reach the module object via the constant.
+A named module is reachable if it is stored in its corresponding constant. It means you can reach the module object via the constant.
That is what ordinarily happens, if a module is called "M", the +M+ constant exists and holds it:
@@ -1016,7 +1015,7 @@ h3. Extensions to +Class+
h4. Class Attributes
-The method +Class#class_attribute+ declares one or more inheritable class attributes that can be overriden at any level down the hierarchy:
+The method +Class#class_attribute+ declares one or more inheritable class attributes that can be overridden at any level down the hierarchy:
<ruby>
class A
@@ -1088,7 +1087,7 @@ NOTE: Defined in +active_support/core_ext/class/attribute_accessors.rb+.
h4. Class Inheritable Attributes
-Class variables are shared down the inheritance tree. Class instance variables are not shared, but they are not inherited either. The macros +class_inheritable_reader+, +class_inheritable_writer+, and +class_inheritable_accessor+ provide accesors for class-level data which is inherited but not shared with children:
+Class variables are shared down the inheritance tree. Class instance variables are not shared, but they are not inherited either. The macros +class_inheritable_reader+, +class_inheritable_writer+, and +class_inheritable_accessor+ provide accessors for class-level data which is inherited but not shared with children:
<ruby>
module ActionController
@@ -1204,7 +1203,7 @@ s.html_safe? # => true
s # => "<script>...</script>"
</ruby>
-It is your responsability to ensure calling +html_safe+ on a particular string is fine.
+It is your responsibility to ensure calling +html_safe+ on a particular string is fine.
NOTE: For performance reasons safe strings are implemented in a way that cannot offer an in-place +html_safe!+ variant.
@@ -1377,7 +1376,7 @@ The method +pluralize+ returns the plural of its receiver:
"equipment".pluralize # => "equipment"
</ruby>
-As the previous example shows, Active Support knows some irregular plurals and uncountable nouns. Builtin rules can be extended in +config/initializers/inflections.rb+. That file is generated by the +rails+ command and has instructions in comments.
+As the previous example shows, Active Support knows some irregular plurals and uncountable nouns. Built-in rules can be extended in +config/initializers/inflections.rb+. That file is generated by the +rails+ command and has instructions in comments.
Active Record uses this method to compute the default table name that corresponds to a model:
@@ -1697,6 +1696,90 @@ foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
+h4. Conversions
+
+h5. +constantize+
+
+The method +constantize+ expects the receiver to contain the name of a constant, and tries to get you the object stored in there, assuming it is defined:
+
+<ruby>
+"ActiveRecord::Base".constantize # => ActiveRecord::Base
+</ruby>
+
+The name is assumed to be top-level, no matter whether it starts with "::" or not. No lexical context is taken into account:
+
+<ruby>
+C = 1
+module M
+ C = 2
+ "C".constantize # => 1, same as "::C".constantize
+end
+</ruby>
+
+NOTE: Defined in +active_support/core_ext/string/conversions.rb+.
+
+h5. +ord+
+
+Ruby 1.9 defines +ord+ to be the codepoint of the first character of the receiver. Active Support backports +ord+ for single-byte encondings like ASCII or ISO-8859-1 in Ruby 1.8:
+
+<ruby>
+"a".ord # => 97
+"à".ord # => 224, in ISO-8859-1
+</ruby>
+
+In Ruby 1.8 +ord+ doesn't work in general in UTF8 strings, use the multibyte support in Active Support for that:
+
+<ruby>
+"a".mb_chars.ord # => 97
+"à".mb_chars.ord # => 224, in UTF8
+</ruby>
+
+Note that the 224 is different in both examples. In ISO-8859-1 "à" is represented as a single byte, 224. Its single-character representattion in UTF8 has two bytes, namely 195 and 160, but its Unicode codepoint is 224. If we call +ord+ on the UTF8 string "à" the return value will be 195 in Ruby 1.8. That is not an error, because UTF8 is unsupported, the call itself would be bogus.
+
+INFO: +ord+ is equivalent to +getbyte(0)+.
+
+NOTE: Defined in +active_support/core_ext/string/conversions.rb+.
+
+h5. +getbyte+
+
+Active Support backports +getbyte+ from Ruby 1.9:
+
+<ruby>
+"foo".getbyte(0) # => 102, same as "foo".ord
+"foo".getbyte(1) # => 111
+"foo".getbyte(9) # => nil
+"foo".getbyte(-1) # => 111
+</ruby>
+
+INFO: +getbyte+ is equivalent to +[]+.
+
+NOTE: Defined in +active_support/core_ext/string/conversions.rb+.
+
+h5. +to_date+, +to_time+, +to_datetime+
+
+The methods +to_date+, +to_time+, and +to_datetime+ are basically convenience wrappers around +Date._parse+:
+
+<ruby>
+"2010-07-27".to_date # => Tue, 27 Jul 2010
+"2010-07-27 23:37:00".to_time # => Tue Jul 27 23:37:00 UTC 2010
+"2010-07-27 23:37:00".to_datetime # => Tue, 27 Jul 2010 23:37:00 +0000
+</ruby>
+
++to_time+ receives an optional argument +:utc+ or +:local+, to indicate which time zone you want the time in:
+
+<ruby>
+"2010-07-27 23:42:00".to_time(:utc) # => Tue Jul 27 23:42:00 UTC 2010
+"2010-07-27 23:42:00".to_time(:local) # => Tue Jul 27 23:42:00 +0200 2010
+</ruby>
+
+Default is +:utc+.
+
+Please refer to the documentation of +Date._parse+ for further details.
+
+INFO: The three of them return +nil+ for blank receivers.
+
+NOTE: Defined in +active_support/core_ext/string/conversions.rb+.
+
h3. Extensions to +Numeric+
h4. Bytes
@@ -1760,7 +1843,7 @@ h3. Extensions to +Float+
h4. +round+
-The builtin method +Float#round+ rounds a float to the nearest integer. Active Support adds an optional parameter to let you specify a precision:
+The built-in method +Float#round+ rounds a float to the nearest integer. Active Support adds an optional parameter to let you specify a precision:
<ruby>
Math::E.round(4) # => 2.7183
@@ -1925,7 +2008,7 @@ Similarly, +from+ returns the tail from the element at the passed index on:
[].from(0) # => []
</ruby>
-The methods +second+, +third+, +fourth+, and +fifth+ return the corresponding element (+first+ is builtin). Thanks to social wisdom and positive constructiveness all around, +forty_two+ is also available.
+The methods +second+, +third+, +fourth+, and +fifth+ return the corresponding element (+first+ is built-in). Thanks to social wisdom and positive constructiveness all around, +forty_two+ is also available.
NOTE: Defined in +active_support/core_ext/array/access.rb+.
@@ -2120,7 +2203,7 @@ NOTE: Defined in +active_support/core_ext/array/conversions.rb+.
h4. Wrapping
-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 behaviour for enumerables:
+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:
<ruby>
Array.wrap(:foo => :bar) # => [{:foo => :bar}]
@@ -2282,7 +2365,7 @@ NOTE: Defined in +active_support/core_ext/hash/conversions.rb+.
h4. Merging
-Ruby has a builtin method +Hash#merge+ that merges two hashes:
+Ruby has a built-in method +Hash#merge+ that merges two hashes:
<ruby>
{:a => 1, :b => 1}.merge(:a => 0, :c => 2)
@@ -2511,7 +2594,7 @@ NOTE: Defined in +active_support/core_ext/hash/keys.rb+.
h4. Slicing
-Ruby has builtin support for taking slices out of strings and arrays. Active Support extends slicing to hashes:
+Ruby has built-in support for taking slices out of strings and arrays. Active Support extends slicing to hashes:
<ruby>
{:a => 1, :b => 2, :c => 3}.slice(:a, :c)
@@ -2625,7 +2708,7 @@ Active Support extends this method so that the argument may be another range in
(1...9).include?(3..9) # => false
</ruby>
-WARNING: The orginal +Range#include?+ is still the one aliased to +Range#===+.
+WARNING: The original +Range#include?+ is still the one aliased to +Range#===+.
NOTE: Defined in +active_support/core_ext/range/include_range.rb+.
@@ -3080,7 +3163,7 @@ Active Support adds +missing_name?+ to +NameError+, which tests whether the exce
The name may be given as a symbol or string. A symbol is tested against the bare constant name, a string is against the fully-qualified constant name.
-TIP: A symbol can represent a fully-qualified constant name as in +:"ActiveRecord::Base"+, so the behaviour for symbols is defined for convenience, not because it has to be that way technically.
+TIP: A symbol can represent a fully-qualified constant name as in +:"ActiveRecord::Base"+, so the behavior for symbols is defined for convenience, not because it has to be that way technically.
For example, when an action of +PostsController+ is called Rails tries optimistically to use +PostsHelper+. It is OK that the helper module does not exist, so if an exception for that constant name is raised it should be silenced. But it could be the case that +posts_helper.rb+ raises a +NameError+ due to an actual unknown constant. That should be reraised. The method +missing_name?+ provides a way to distinguish both cases:
diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile
index 515b3aad39..1f1b7d076e 100644
--- a/railties/guides/source/form_helpers.textile
+++ b/railties/guides/source/form_helpers.textile
@@ -205,7 +205,7 @@ Upon form submission the value entered by the user will be stored in +params[:pe
WARNING: You must pass the name of an instance variable, i.e. +:person+ or +"person"+, not an actual instance of your model object.
-Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the "Active Record Validations and Callbacks":./activerecord_validations_callbacks.html#displaying-validation-errors-in-the-view guide.
+Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the "Active Record Validations and Callbacks":./active_record_validations_callbacks.html#displaying-validation-errors-in-the-view guide.
h4. Binding a Form to an Object
diff --git a/railties/guides/source/generators.textile b/railties/guides/source/generators.textile
index 704a8793b2..c5b41673e1 100644
--- a/railties/guides/source/generators.textile
+++ b/railties/guides/source/generators.textile
@@ -1,21 +1,21 @@
-h2. Creating and customizing Rails Generators
+h2. Creating and Customizing Rails Generators
Rails generators are an essential tool if you plan to improve your workflow and in this guide you will learn how to create and customize already existing generators.
In this guide you will:
-* Learn how to see which generators are available in your application;
-* Create a generator using templates;
-* Learn how Rails searches for generators before invoking them;
-* Customize your scaffold by creating new generators;
-* Customize your scaffold by changing generators templates;
-* Learn how to use fallbacks to avoid overwriting a huge set of generators;
+* Learn how to see which generators are available in your application
+* Create a generator using templates
+* Learn how Rails searches for generators before invoking them
+* Customize your scaffold by creating new generators
+* Customize your scaffold by changing generator templates
+* Learn how to use fallbacks to avoid overwriting a huge set of generators
endprologue.
NOTE: This guide is about Rails generators for versions >= 3.0. Rails generators from previous versions are not supported.
-h3. First contact
+h3. First Contact
When you create an application using the +rails+ command, you are in fact using a Rails generator. After that, you can get a list of all available generators by just invoking +rails generate+:
@@ -25,15 +25,15 @@ $ cd myapp
$ rails generate
</shell>
-You will get a list of all generators that comes with Rails. If you need a detailed description, for instance about the helper generator, you can simply do:
+You will get a list of all generators that comes with Rails. If you need a detailed description of the helper generator, for example, you can simply do:
<shell>
$ rails generate helper --help
</shell>
-h3. Creating your first generator
+h3. Creating Your First Generator
-Since Rails 3.0, generators are built on top of "Thor":http://github.com/wycats/thor. Thor has a powerful options parsing and a great API for manipulating files. For instance, let's build a generator that creates an initializer file named +initializer.rb+ inside +config/initializers+.
+Since Rails 3.0, generators are built on top of "Thor":http://github.com/wycats/thor. Thor provides powerful options parsing and a great API for manipulating files. For instance, let's build a generator that creates an initializer file named +initializer.rb+ inside +config/initializers+.
The first step is to create a file at +RAILS_APP/lib/generators/initializer_generator.rb+ with the following content:
@@ -45,7 +45,7 @@ class InitializerGenerator < Rails::Generators::Base
end
</ruby>
-Our new generator is quite simple: it inherits from +Rails::Generators::Base+ and have one method definition. Each public method in the generator is executed when a generator is invoked. Finally, we invoke the +create_file+ method that will create a file at the given destination with the given content. If you are familiar with Rails Application Templates API, you are at home with new generators API.
+Our new generator is quite simple: it inherits from +Rails::Generators::Base+ and has one method definition. Each public method in the generator is executed when a generator is invoked. Finally, we invoke the +create_file+ method that will create a file at the given destination with the given content. If you are familiar with the Rails Application Templates API, you'll feel right at home with the new generators API.
To invoke our new generator, we just need to do:
@@ -59,7 +59,7 @@ Before we go on, let's see our brand new generator description:
$ rails generate initializer --help
</shell>
-Rails usually is able to generate good descriptions if a generator is namespaced, as +ActiveRecord::Generators::ModelGenerator+, but not in this particular case. We can solve this problem in two ways. The first one is calling +desc+ inside our generator:
+Rails is usually able to generate good descriptions if a generator is namespaced, as +ActiveRecord::Generators::ModelGenerator+, but not in this particular case. We can solve this problem in two ways. The first one is calling +desc+ inside our generator:
<ruby>
class InitializerGenerator < Rails::Generators::Base
@@ -70,9 +70,9 @@ class InitializerGenerator < Rails::Generators::Base
end
</ruby>
-Now we can see the new description by invoking +--help+ in the new generator. The second way to add a description is by creating a file named +USAGE+ in the same directory as our generator. We are going to do that in the next step.
+Now we can see the new description by invoking +--help+ on the new generator. The second way to add a description is by creating a file named +USAGE+ in the same directory as our generator. We are going to do that in the next step.
-h3. Creating generators with generators
+h3. Creating Generators with Generators
A faster way to create a generator is using the generator's generator:
@@ -84,7 +84,7 @@ $ rails generate generator initializer
create lib/generators/initializer/templates
</shell>
-And it will create a new generator as follow:
+And it will create a new generator as follows:
<ruby>
class InitializerGenerator < Rails::Generators::NamedBase
@@ -92,7 +92,7 @@ class InitializerGenerator < Rails::Generators::NamedBase
end
</ruby>
-At first, we can notice that we are inheriting from +Rails::Generators::NamedBase+ instead of +Rails::Generators::Base+. This means that our generator expects as least one argument, which will be the name of the initializer.
+First, notice that we are inheriting from +Rails::Generators::NamedBase+ instead of +Rails::Generators::Base+. This means that our generator expects as least one argument, which will be the name of the initializer.
We can see that by invoking the description of this new generator (don't forget to delete the old generator file):
@@ -127,13 +127,13 @@ And let's execute our generator:
$ rails generate initializer foo
</shell>
-We can see that now a initializer named foo was created at +config/initializers/foo.rb+ with the contents of our template. That means that copy_file copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+.
+We can see that now a initializer named foo was created at +config/initializers/foo.rb+ with the contents of our template. That means that +copy_file+ copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+.
-h3. Generators lookup
+h3. Generators Lookup
-With our first generator created, we must discuss briefly generators lookup. The way Rails finds generators is exactly the same way Ruby find files, i.e. using +$LOAD_PATHS+.
+Now that we've created our first generator, we need to briefly discuss generator lookup. The way Rails finds generators is exactly the same way Ruby find files, i.e. using +$LOAD_PATHS+.
-For instance, when you say +rails g initializer foo+, rails knows you want to invoke the initializer generator and then search for the following generators in the $LOAD_PATHS:
+For instance, when you say +rails generate initializer foo+, Rails knows you want to invoke the initializer generator and then search for the following generators in the $LOAD_PATHS:
<shell>
rails/generators/initializer/initializer_generator.rb
@@ -144,7 +144,7 @@ generators/initializer_generator.rb
If none of them is found, it raises an error message.
-h3. Customizing your workflow
+h3. Customizing Your Workflow
Rails generators are flexible enough to let you customize your scaffold the way you want. In your +config/application.rb+ there is a section just for generators:
@@ -156,7 +156,7 @@ config.generators do |g|
end
</ruby>
-Before we customize our workflow, let's first see how our scaffold looks like:
+Before we customize our workflow, let's first see what our scaffold looks like:
<shell>
$ rails generate scaffold User name:string
@@ -186,7 +186,7 @@ $ rails generate scaffold User name:string
create public/stylesheets/scaffold.css
</shell>
-Looking at this output, is easy to understand how generators work on Rails 3.0 and above. The scaffold generator actually doesn't generate anything, it just invokes others to do the work. This allows us to add/replace/remove any of those invocations. For instance, the scaffold generator invokes the scaffold_controller generator, which invokes erb, test_unit and helper generators. Since each generator has a single responsibility, they are easy to reuse, avoiding code duplication.
+Looking at this output, it's easy to understand how generators work on Rails 3.0 and above. The scaffold generator doesn't actually generate anything, it just invokes others to do the work. This allows us to add/replace/remove any of those invocations. For instance, the scaffold generator invokes the scaffold_controller generator, which invokes erb, test_unit and helper generators. Since each generator has a single responsibility, they are easy to reuse, avoiding code duplication.
Our first customization on the workflow will be to stop generating stylesheets and test fixtures on scaffold. We can achieve that by changing our application to the following:
@@ -199,15 +199,15 @@ config.generators do |g|
end
</ruby>
-If we generate another resource on scaffold, we can notice that neither stylesheets nor fixtures are created anymore. If you want to customize it further, for example to use +Datamapper+ and +Rspec+ instead of +ActiveRecord+ and +TestUnit+, is just a matter of adding their gems to your application and configuring your generators.
+If we generate another resource on scaffold, we can notice that neither stylesheets nor fixtures are created anymore. If you want to customize it further, for example to use +Datamapper+ and +RSpec+ instead of +ActiveRecord+ and +TestUnit+, it's just a matter of adding their gems to your application and configuring your generators.
-To show that, we are going to create a new helper generator that simply adds some instance variable readers. First, we create a generator:
+To demonstrate this, we are going to create a new helper generator that simply adds some instance variable readers. First, we create a generator:
<shell>
$ rails generate generator my_helper
</shell>
-After that, we can delete both templates directory and the +source_root+ class method from our new generators, because we are not going to need them. So our new generator looks like the following:
+After that, we can delete both the +templates+ directory and the +source_root+ class method from our new generators, because we are not going to need them. So our new generator looks like the following:
<ruby>
class MyHelperGenerator < Rails::Generators::NamedBase
@@ -227,7 +227,7 @@ We can try out our new generator by creating a helper for users:
$ rails generate my_helper users
</shell>
-And it will generate the following helper file in app/helpers:
+And it will generate the following helper file in +app/helpers+:
<ruby>
module UsersHelper
@@ -258,7 +258,7 @@ $ rails generate scaffold Post body:text
We can notice on the output that our new helper was invoked instead of the Rails default. However one thing is missing, which is tests for our new generator and to do that, we are going to reuse old helpers test generators.
-Since Rails 3.0, this is easy to do due to the hooks concept. Our new helper does not need to be focused in one specific test framework, it can simply provide a hook and a test framework just need to implement this hook in order to be compatible.
+Since Rails 3.0, this is easy to do due to the hooks concept. Our new helper does not need to be focused in one specific test framework, it can simply provide a hook and a test framework just needs to implement this hook in order to be compatible.
To do that, we can change your generator to the following:
@@ -276,7 +276,7 @@ end
end
</ruby>
-Now, when the helper generator is invoked and let's say test unit is configured as test framework, it will try to invoke both +MyHelper::Generators::TestUnitGenerator+ and +TestUnit::Generators::MyHelperGenerator+. Since none of those are defined, we can tell our generator to invoke +TestUnit::Generators::HelperGenerator+ instead, which is defined since it's a Rails generator. To do that, we just need to add:
+Now, when the helper generator is invoked and TestUnit is configured as the test framework, it will try to invoke both +MyHelper::Generators::TestUnitGenerator+ and +TestUnit::Generators::MyHelperGenerator+. Since none of those are defined, we can tell our generator to invoke +TestUnit::Generators::HelperGenerator+ instead, which is defined since it's a Rails generator. To do that, we just need to add:
<ruby>
# Search for :helper instead of :my_helper
@@ -285,11 +285,11 @@ Now, when the helper generator is invoked and let's say test unit is configured
And now you can re-run scaffold for another resource and see it generating tests as well!
-h3. Customizing your workflow by changing generators templates
+h3. Customizing Your Workflow by Changing Generators Templates
In the step above, we simply wanted to add a line to the generated helper, without adding any extra functionality. There is a simpler way to do that, and it's by replacing the templates of already existing generators.
-In Rails 3.0 and above, generators does not look only in the source root for templates, they also search for templates in other paths. And one of them is inside +RAILS_APP/lib/templates+. Since we want to customize +Rails::Generators::HelperGenerator+, we can do that by simple making a template copy inside +RAILS_APP/lib/templates/rails/helper+ with the name +helper.rb+. So let's create such file with the following content:
+In Rails 3.0 and above, generators don't just look in the source root for templates, they also search for templates in other paths. And one of them is inside +RAILS_APP/lib/templates+. Since we want to customize +Rails::Generators::HelperGenerator+, we can do that by simply making a template copy inside +RAILS_APP/lib/templates/rails/helper+ with the name +helper.rb+. So let's create that file with the following content:
<erb>
module <%= class_name %>Helper
@@ -310,9 +310,9 @@ end
If you generate another resource, you can see that we got exactly the same result! This is useful if you want to customize your scaffold templates and/or layout by just creating +edit.html.erb+, +index.html.erb+ and so on inside +RAILS_APP/lib/templates/erb/scaffold+.
-h3. Adding generators fallbacks
+h3. Adding Generators Fallbacks
-One last feature about generators which is quite useful for plugin generators is fallbacks. For example, imagine that you want to add a feature on top of TestUnit test framework, like "shoulda":http://github.com/thoughtbot/shoulda does. Since TestUnit already implements all generators required by Rails and shoulda just want to overwrite part of it, there is no need for shoulda to reimplement some generators again, they can simply tell Rails to use a +TestUnit+ generator if none was found under +Shoulda+ namespace.
+One last feature about generators which is quite useful for plugin generators is fallbacks. For example, imagine that you want to add a feature on top of TestUnit test framework, like "shoulda":http://github.com/thoughtbot/shoulda does. Since TestUnit already implements all generators required by Rails and shoulda just wants to overwrite part of it, there is no need for shoulda to reimplement some generators again, it can simply tell Rails to use a +TestUnit+ generator if none was found under the +Shoulda+ namespace.
We can easily simulate this behavior by changing our +config/application.rb+ once again:
@@ -324,11 +324,11 @@ config.generators do |g|
g.stylesheets false
# Add a fallback!
- g.fallbacks[:should] = :test_unit
+ g.fallbacks[:shoulda] = :test_unit
end
</ruby>
-Now, if create a Comment scaffold, you will see that shoulda generators are being invoked, and at the end, they are just falling back to test unit generators:
+Now, if you create a Comment scaffold, you will see that the shoulda generators are being invoked, and at the end, they are just falling back to test unit generators:
<shell>
$ rails generate scaffold Comment body:text
@@ -357,7 +357,7 @@ $ rails generate scaffold Comment body:text
create test/unit/helpers/comments_helper_test.rb
</shell>
-Such tool allows your generators to have single responsibility, increasing the code reuse and reducing the amount of duplication.
+Fallbacks allow your generators to have a single responsibility, increasing code reuse and reducing the amount of duplication.
h3. Changelog
diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile
index 7b4f1ca471..6abb3ed9f4 100644
--- a/railties/guides/source/getting_started.textile
+++ b/railties/guides/source/getting_started.textile
@@ -227,7 +227,7 @@ development:
timeout: 5000
</yaml>
-NOTE: In this guide we are using an SQLite3 database for data storage, this is because it is a zero configuration database that just works. Rails also supports MySQL and PostgreSQL "out of the box", and has plugins for many database systems, if you are using a database in a production environment, Rails most likely has an adapter for it.
+NOTE: In this guide we are using an SQLite3 database for data storage, because it is a zero configuration database that just works. Rails also supports MySQL and PostgreSQL "out of the box", and has plugins for many database systems. If you are using a database in a production environment Rails most likely has an adapter for it.
h5. Configuring a MySQL Database
diff --git a/railties/guides/source/index.html.erb b/railties/guides/source/index.html.erb
index 5a715cf9f7..be077fcd2f 100644
--- a/railties/guides/source/index.html.erb
+++ b/railties/guides/source/index.html.erb
@@ -47,7 +47,7 @@ Ruby on Rails Guides
<p>This guide covers how you can use Active Record migrations to alter your database in a structured and organized manner.</p>
<% end %>
-<%= guide("Active Record Validations and Callbacks", 'activerecord_validations_callbacks.html') do %>
+<%= guide("Active Record Validations and Callbacks", 'active_record_validations_callbacks.html') do %>
<p>This guide covers how you can use Active Record validations and callbacks.</p>
<% end %>
diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile
index bc3a2d0f0b..e458413b35 100644
--- a/railties/guides/source/initialization.textile
+++ b/railties/guides/source/initialization.textile
@@ -148,7 +148,7 @@ Here the only two gems we need are +rails+ and +sqlite3-ruby+, so it seems. This
* mime-types-1.16.gem
* polyglot-0.3.1.gem
* rack-1.1.0.gem
-* rack-mount-0.6.4.gem
+* rack-mount-0.6.5.gem
* rack-test-0.5.4.gem
* rails-3.0.0.beta4.gem
* railties-3.0.0.beta4.gem
diff --git a/railties/guides/source/layout.html.erb b/railties/guides/source/layout.html.erb
index f1727166ba..501d8fef6d 100644
--- a/railties/guides/source/layout.html.erb
+++ b/railties/guides/source/layout.html.erb
@@ -50,7 +50,7 @@
<dd><a href="getting_started.html">Getting Started with Rails</a></dd>
<dt>Models</dt>
<dd><a href="migrations.html">Rails Database Migrations</a></dd>
- <dd><a href="activerecord_validations_callbacks.html">Active Record Validations and Callbacks</a></dd>
+ <dd><a href="active_record_validations_callbacks.html">Active Record Validations and Callbacks</a></dd>
<dd><a href="association_basics.html">Active Record Associations</a></dd>
<dd><a href="active_record_querying.html">Active Record Query Interface</a></dd>
<dt>Views</dt>
diff --git a/railties/guides/source/rails_application_templates.textile b/railties/guides/source/rails_application_templates.textile
index 1af6f56957..1bf9cfec33 100644
--- a/railties/guides/source/rails_application_templates.textile
+++ b/railties/guides/source/rails_application_templates.textile
@@ -51,11 +51,11 @@ h4. gem(name, options = {})
Adds a +config.gem+ entry for the supplied gem to the generated application’s +config/environment.rb+.
-For example, if your application depends on the gems +bj+ and +hpricot+ :
+For example, if your application depends on the gems +bj+ and +nokogiri+ :
<ruby>
gem "bj"
-gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
+gem "nokogiri"
</ruby>
Please note that this will NOT install the gems for you. So you may want to run the +rake gems:install+ task too :
diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile
index 54af42a03f..9ff06856c3 100644
--- a/railties/guides/source/routing.textile
+++ b/railties/guides/source/routing.textile
@@ -32,7 +32,7 @@ the request is dispatched to the +patients+ controller's +show+ action with <tt>
h4. Generating URLs from Code
-You can also generate routes. If your application contains this code:
+You can also generate URLs. If your application contains this code:
<ruby>
@patient = Patient.find(17)
@@ -308,7 +308,7 @@ You are not limited to the seven routes that RESTful routing creates by default.
h5. Adding Member Routes
-To add a member route, just add +member+ block into resource block:
+To add a member route, just add a +member+ block into the resource block:
<ruby>
resources :photos do
@@ -318,9 +318,9 @@ resources :photos do
end
</ruby>
-This will recognize +/photos/1/preview+ with GET, and route to the +preview+ action of +PhotosController+. It will also create the +preview_photo_url+ and +preview_photo_path+ helpers.
+This will recognize +/photos/1/preview+ with GET, and route to the +preview+ action of +PhotosController+. It will also create the +preview_photo_url+ and +preview_photo_path+ helpers.
-Within the block of member routes, each route name specifies the HTTP verb that it will recognize. You can use +get+, +put+, +post+, or +delete+ here. If you don't have multiple +member+ routes, you can also passing +:on+ to a route.
+Within the block of member routes, each route name specifies the HTTP verb that it will recognize. You can use +get+, +put+, +post+, or +delete+ here. If you don't have multiple +member+ routes, you can also pass +:on+ to a route, eliminating the block:
<ruby>
resources :photos do
@@ -340,9 +340,9 @@ resources :photos do
end
</ruby>
-This will enable Rails to recognize URLs such as +/photos/search+ with GET, and route to the +search+ action of +PhotosController+. It will also create the +search_photos_url+ and +search_photos_path+ route helpers.
+This will enable Rails to recognize URLs such as +/photos/search+ with GET, and route to the +search+ action of +PhotosController+. It will also create the +search_photos_url+ and +search_photos_path+ route helpers.
-Just as with member routes, you can pass +:on+ to a route.
+Just as with member routes, you can pass +:on+ to a route:
<ruby>
resources :photos do
@@ -384,7 +384,7 @@ An incoming URL of +/photos/show/1/2+ will be dispatched to the +show+ action of
h4. Static Segments
-You can specify static segments when creating a route.
+You can specify static segments when creating a route:
<ruby>
match ':controller/:action/:id/with_user/:user_id'
@@ -444,6 +444,21 @@ This route would match URLs such as +/photo/A12345+. You can more succinctly exp
match 'photo/:id' => 'photos#show', :id => /[A-Z]\d{5}/
</ruby>
++:constraints+ takes regular expression. However note that regexp anchors can't be used within constraints. For example following route will not work:
+
+<ruby>
+match '/:id' => 'posts#show', :constraints => {:id => /^\d/}
+</ruby>
+
+However, note that you don't need to use anchors because all routes are anchored at the start.
+
+For example, the following routes would allow for +posts+ with +to_param+ values like +1-hello-world+ that always begin with a number and +users+ with +to_param+ values like +david+ that never begin with a number to share the root namespace:
+
+<ruby>
+match '/:id' => 'posts#show', :constraints => { :id => /\d.+/ }
+match '/:username' => 'users#show'
+</ruby>
+
h4. Request-Based Constraints
You can also constrain a route based on any method on the <a href="action_controller_overview.html#the-request-object">Request</a> object that returns a +String+.
@@ -575,7 +590,7 @@ resources :photos, :constraints => {:id => /[A-Z][A-Z][0-9]+/}
This declaration constrains the +:id+ parameter to match the supplied regular expression. So, in this case, the router would no longer match +/photos/1+ to this route. Instead, +/photos/RR27+ would match.
-You can specify a single constraint to a apply to a number of routes by using the block form:
+You can specify a single constraint to apply to a number of routes by using the block form:
<ruby>
constraints(:id => /[A-Z][A-Z][0-9]+/) do
diff --git a/railties/guides/w3c_validator.rb b/railties/guides/w3c_validator.rb
index b55645a7a9..4da48bf3fb 100644
--- a/railties/guides/w3c_validator.rb
+++ b/railties/guides/w3c_validator.rb
@@ -35,23 +35,27 @@ module RailsGuides
def validate
validator = MarkupValidator.new
+ STDOUT.sync = true
+ errors_on_guides = {}
guides_to_validate.each do |f|
- puts "Validating #{f}"
results = validator.validate_file(f)
- if !results.validity
- puts "#{f} FAILED W3C validation with #{results.errors.size} error(s):"
- results.errors.each do |error|
- puts error.to_s
- end
+ if results.validity
+ print "."
+ else
+ print "E"
+ errors_on_guides[f] = results.errors
end
end
+
+ show_results(errors_on_guides)
end
private
def guides_to_validate
guides = Dir["./guides/output/*.html"]
+ guides.delete("./guides/output/layout.html")
ENV.key?('ONLY') ? select_only(guides) : guides
end
@@ -61,6 +65,26 @@ module RailsGuides
prefixes.any? {|p| guide.start_with?("./guides/output/#{p}")}
end
end
+
+ def show_results(error_list)
+ if error_list.size == 0
+ puts "\n\nAll checked guides validate OK!"
+ else
+ error_summary = error_detail = ""
+
+ error_list.each_pair do |name, errors|
+ error_summary += "\n #{name}"
+ error_detail += "\n\n #{name} has #{errors.size} validation error(s):\n"
+ errors.each do |error|
+ error_detail += "\n "+error.to_s.gsub("\n", "")
+ end
+ end
+
+ puts "\n\nThere are #{error_list.size} guides with validation errors:\n" + error_summary
+ puts "\nHere are the detailed errors for each guide:" + error_detail
+ end
+ end
+
end
end
diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb
index ed66f493e6..bbf28a8c08 100644
--- a/railties/lib/rails.rb
+++ b/railties/lib/rails.rb
@@ -9,7 +9,6 @@ require 'active_support/core_ext/logger'
require 'rails/application'
require 'rails/version'
require 'rails/deprecation'
-require 'rails/log_subscriber'
require 'active_support/railtie'
require 'action_dispatch/railtie'
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 85ae8cbbb1..4a7ed2d028 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/hash/reverse_merge'
+require 'active_support/file_update_checker'
require 'fileutils'
require 'rails/plugin'
require 'rails/engine'
@@ -27,7 +28,7 @@ module Rails
# Besides providing the same configuration as Rails::Engine and Rails::Railtie,
# the application object has several specific configurations, for example
# "allow_concurrency", "cache_classes", "consider_all_requests_local", "filter_parameters",
- # "logger", "reload_engines", "reload_plugins" and so forth.
+ # "logger", "reload_plugins" and so forth.
#
# Check Rails::Application::Configuration to see them all.
#
@@ -46,7 +47,6 @@ module Rails
autoload :Configuration, 'rails/application/configuration'
autoload :Finisher, 'rails/application/finisher'
autoload :Railties, 'rails/application/railties'
- autoload :RoutesReloader, 'rails/application/routes_reloader'
class << self
private :new
@@ -67,7 +67,7 @@ module Rails
raise "You cannot have more than one Rails::Application" if Rails.application
super
Rails.application = base.instance
- Rails.application.add_lib_to_load_paths!
+ Rails.application.add_lib_to_load_path!
ActiveSupport.run_load_hooks(:before_configuration, base.instance)
end
@@ -84,17 +84,30 @@ module Rails
delegate :middleware, :to => :config
- def add_lib_to_load_paths!
+ # This method is called just after an application inherits from Rails::Application,
+ # allowing the developer to load classes in lib and use them during application
+ # configuration.
+ #
+ # class MyApplication < Rails::Application
+ # require "my_backend" # in lib/my_backend
+ # config.i18n.backend = MyBackend
+ # end
+ #
+ # Notice this method takes into consideration the default root path. So if you
+ # are changing config.root inside your application definition or having a custom
+ # Rails application, you will need to add lib to $LOAD_PATH on your own in case
+ # you need to load files in lib/ during the application configuration as well.
+ def add_lib_to_load_path! #:nodoc:
path = config.root.join('lib').to_s
$LOAD_PATH.unshift(path) if File.exists?(path)
end
- def require_environment!
+ def require_environment! #:nodoc:
environment = paths.config.environment.to_a.first
require environment if environment
end
- def eager_load!
+ def eager_load! #:nodoc:
railties.all(&:eager_load!)
super
end
@@ -108,11 +121,18 @@ module Rails
end
def routes_reloader
- @routes_reloader ||= RoutesReloader.new
+ @routes_reloader ||= ActiveSupport::FileUpdateChecker.new([]){ reload_routes! }
end
def reload_routes!
- routes_reloader.reload!
+ routes = Rails::Application.routes
+ routes.disable_clear_and_finalize = true
+
+ routes.clear!
+ routes_reloader.paths.each { |path| load(path) }
+ ActiveSupport.on_load(:action_controller) { routes.finalize! }
+ ensure
+ routes.disable_clear_and_finalize = false
end
def initialize!
@@ -140,6 +160,7 @@ module Rails
config.middleware.build(routes)
end
end
+ alias :build_middleware_stack :app
def call(env)
app.call(env.reverse_merge!(env_defaults))
@@ -196,10 +217,5 @@ module Rails
def initialize_generators
require "rails/generators"
end
-
- # Application is always reloadable when config.cache_classes is false.
- def reloadable?(app)
- true
- end
end
end
diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb
index 0a435f0f36..44e26b5713 100644
--- a/railties/lib/rails/application/bootstrap.rb
+++ b/railties/lib/rails/application/bootstrap.rb
@@ -1,4 +1,5 @@
require "active_support/notifications"
+require "active_support/descendants_tracker"
module Rails
class Application
@@ -55,6 +56,7 @@ module Rails
initializer :set_clear_dependencies_hook do
unless config.cache_classes
ActionDispatch::Callbacks.after do
+ ActiveSupport::DescendantsTracker.clear
ActiveSupport::Dependencies.clear
end
end
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 25e54e9dce..465851c0e6 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -10,7 +10,7 @@ module Rails
attr_accessor :allow_concurrency, :cache_classes, :cache_store,
:encoding, :consider_all_requests_local, :dependency_loading,
:filter_parameters, :log_level, :logger, :middleware,
- :plugins, :preload_frameworks, :reload_engines, :reload_plugins,
+ :plugins, :preload_frameworks, :reload_plugins,
:secret_token, :serve_static_assets, :session_options,
:time_zone, :whiny_nils
@@ -59,7 +59,7 @@ module Rails
if File.exists?("#{root}/test/mocks/#{Rails.env}")
ActiveSupport::Deprecation.warn "\"Rails.root/test/mocks/#{Rails.env}\" won't be added " <<
"automatically to load paths anymore in future releases"
- paths.mocks_path "test/mocks", :load_path => true, :glob => Rails.env
+ paths.mocks_path "test/mocks", :autoload => true, :glob => Rails.env
end
paths
@@ -110,7 +110,7 @@ module Rails
def colorize_logging=(val)
@colorize_logging = val
- Rails::LogSubscriber.colorize_logging = val
+ ActiveSupport::LogSubscriber.colorize_logging = val
self.generators.colorize_logging = val
end
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index d7ff489336..855467227b 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -7,14 +7,14 @@ module Rails
config.generators.templates.unshift(*paths.lib.templates.to_a)
end
- initializer :ensure_load_once_paths_as_subset do
- extra = ActiveSupport::Dependencies.load_once_paths -
- ActiveSupport::Dependencies.load_paths
+ initializer :ensure_autoload_once_paths_as_subset do
+ extra = ActiveSupport::Dependencies.autoload_once_paths -
+ ActiveSupport::Dependencies.autoload_paths
unless extra.empty?
abort <<-end_error
- load_once_paths must be a subset of the load_paths.
- Extra items in load_once_paths: #{extra * ','}
+ autoload_once_paths must be a subset of the autoload_paths.
+ Extra items in autoload_once_paths: #{extra * ','}
end_error
end
end
@@ -32,7 +32,7 @@ module Rails
end
initializer :build_middleware_stack do
- app
+ build_middleware_stack
end
initializer :eager_load! do
diff --git a/railties/lib/rails/application/routes_reloader.rb b/railties/lib/rails/application/routes_reloader.rb
deleted file mode 100644
index a2b3622df8..0000000000
--- a/railties/lib/rails/application/routes_reloader.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-module Rails
- class Application
- class RoutesReloader
- attr_reader :paths
-
- def initialize
- @paths, @last_change_at = [], nil
- end
-
- def changed_at
- routes_changed_at = nil
-
- paths.each do |path|
- config_changed_at = File.stat(path).mtime
-
- if routes_changed_at.nil? || config_changed_at > routes_changed_at
- routes_changed_at = config_changed_at
- end
- end
-
- routes_changed_at
- end
-
- def reload!
- routes = Rails::Application.routes
- routes.disable_clear_and_finalize = true
-
- routes.clear!
- paths.each { |path| load(path) }
- ActiveSupport.on_load(:action_controller) { routes.finalize! }
-
- nil
- ensure
- routes.disable_clear_and_finalize = false
- end
-
- def reload_if_changed
- current_change_at = changed_at
- if @last_change_at != current_change_at
- @last_change_at = current_change_at
- reload!
- end
- end
- end
- end
-end \ No newline at end of file
diff --git a/railties/lib/rails/commands/generate.rb b/railties/lib/rails/commands/generate.rb
index 1b3eef504a..1b3eef504a 100755..100644
--- a/railties/lib/rails/commands/generate.rb
+++ b/railties/lib/rails/commands/generate.rb
diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb
index 278548558e..b97ff086b6 100644
--- a/railties/lib/rails/commands/runner.rb
+++ b/railties/lib/rails/commands/runner.rb
@@ -44,6 +44,7 @@ begin
$stderr.puts "Run '#{$0} -h' for help."
exit 1
elsif File.exist?(code_or_file)
+ $0 = code_or_file
eval(File.read(code_or_file), nil, code_or_file)
else
eval(code_or_file)
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 3f74cd49fc..9d9dd48ea9 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -9,7 +9,7 @@ module Rails
args, options = args.dup, {}
opt_parser = OptionParser.new do |opts|
- opts.banner = "Usage: rails server [options]"
+ opts.banner = "Usage: rails server [mongrel, thin, etc] [options]"
opts.on("-p", "--port=port", Integer,
"Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v }
opts.on("-b", "--binding=ip", String,
@@ -83,7 +83,8 @@ module Rails
:environment => (ENV['RAILS_ENV'] || "development").dup,
:daemonize => false,
:debugger => false,
- :pid => "tmp/pids/server.pid"
+ :pid => File.expand_path("tmp/pids/server.pid"),
+ :config => File.expand_path("config.ru")
})
end
end
diff --git a/railties/lib/rails/console/app.rb b/railties/lib/rails/console/app.rb
index 4a7701081b..9d9763699d 100644
--- a/railties/lib/rails/console/app.rb
+++ b/railties/lib/rails/console/app.rb
@@ -30,5 +30,3 @@ def reload!(print=true)
ActionDispatch::Callbacks.new(Proc.new {}, false).call({})
true
end
-
-reload!(false)
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index cdb00a4eff..ee3e3ba040 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -32,14 +32,14 @@ module Rails
# == Configuration
#
# Besides the Railtie configuration which is shared across the application, in a
- # Rails::Engine you can access load_paths, eager_load_paths and load_once_paths,
+ # Rails::Engine you can access autoload_paths, eager_load_paths and autoload_once_paths,
# which differently from a Railtie, are scoped to the current Engine.
#
# Example:
#
# class MyEngine < Rails::Engine
# # Add a load path for this specific Engine
- # config.load_paths << File.expand_path("../lib/some/path", __FILE__)
+ # config.autoload_paths << File.expand_path("../lib/some/path", __FILE__)
#
# initializer "my_engine.add_middleware" do |app|
# app.middleware.use MyEngine::Middleware
@@ -142,7 +142,7 @@ module Rails
# Add configured load paths to ruby load paths and remove duplicates.
initializer :set_load_path, :before => :bootstrap_hook do
- config.load_paths.reverse_each do |path|
+ _all_load_paths.reverse_each do |path|
$LOAD_PATH.unshift(path) if File.directory?(path)
end
$LOAD_PATH.uniq!
@@ -154,17 +154,13 @@ module Rails
# This needs to be an initializer, since it needs to run once
# per engine and get the engine as a block parameter
initializer :set_autoload_paths, :before => :bootstrap_hook do |app|
- ActiveSupport::Dependencies.load_paths.unshift(*config.load_paths)
-
- if reloadable?(app)
- ActiveSupport::Dependencies.load_once_paths.unshift(*config.load_once_paths)
- else
- ActiveSupport::Dependencies.load_once_paths.unshift(*config.load_paths)
- end
+ ActiveSupport::Dependencies.autoload_paths.unshift(*_all_autoload_paths)
+ ActiveSupport::Dependencies.autoload_once_paths.unshift(*config.autoload_once_paths)
# Freeze so future modifications will fail rather than do nothing mysteriously
- config.load_paths.freeze
- config.load_once_paths.freeze
+ config.autoload_paths.freeze
+ config.eager_load_paths.freeze
+ config.autoload_once_paths.freeze
end
initializer :add_routing_paths do |app|
@@ -195,7 +191,6 @@ module Rails
ActiveSupport.on_load(:action_controller) do
prepend_view_path(views)
end
-
ActiveSupport.on_load(:action_mailer) do
prepend_view_path(views)
end
@@ -214,8 +209,12 @@ module Rails
protected
- def reloadable?(app)
- app.config.reload_engines
+ def _all_autoload_paths
+ @_all_autoload_paths ||= (config.autoload_paths + config.eager_load_paths + config.autoload_once_paths).uniq
+ end
+
+ def _all_load_paths
+ @_all_load_paths ||= (config.paths.load_paths + _all_autoload_paths).uniq
end
end
end
diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb
index 446fe0bda9..2f465670cf 100644
--- a/railties/lib/rails/engine/configuration.rb
+++ b/railties/lib/rails/engine/configuration.rb
@@ -4,7 +4,7 @@ module Rails
class Engine
class Configuration < ::Rails::Railtie::Configuration
attr_reader :root
- attr_writer :eager_load_paths, :load_once_paths, :load_paths
+ attr_writer :eager_load_paths, :autoload_once_paths, :autoload_paths
def initialize(root=nil)
super()
@@ -41,12 +41,12 @@ module Rails
@eager_load_paths ||= paths.eager_load
end
- def load_once_paths
- @load_once_paths ||= paths.load_once
+ def autoload_once_paths
+ @autoload_once_paths ||= paths.autoload_once
end
- def load_paths
- @load_paths ||= paths.load_paths
+ def autoload_paths
+ @autoload_paths ||= paths.autoload_paths
end
end
end
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 41aecea355..8794392a7d 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -50,7 +50,6 @@ module Rails
:performance_tool => nil,
:resource_controller => :controller,
:scaffold_controller => :scaffold_controller,
- :singleton => false,
:stylesheets => true,
:test_framework => nil,
:template_engine => :erb
@@ -334,4 +333,4 @@ module Rails
paths
end
end
-end \ No newline at end of file
+end
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index 7af329bbf0..199afbdc30 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -275,7 +275,7 @@ module Rails
#
def route(routing_code)
log :route, routing_code
- sentinel = "routes.draw do |map|"
+ sentinel = /\.routes\.draw do(\s*\|map\|)?\s*$/
in_root do
inject_into_file 'config/routes.rb', "\n #{routing_code}\n", { :after => sentinel, :verbose => false }
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb
index bd2260fc29..67a9a6030d 100644
--- a/railties/lib/rails/generators/base.rb
+++ b/railties/lib/rails/generators/base.rb
@@ -3,7 +3,7 @@ begin
rescue LoadError
puts "Thor is not available.\nIf you ran this command from a git checkout " \
"of Rails, please make sure thor is installed,\nand run this command " \
- "as `ruby /path/to/rails myapp --dev`"
+ "as `ruby /path/to/rails new myapp --dev`"
exit
end
diff --git a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
index 2db7f7bbf3..b2c8d7051b 100644
--- a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
@@ -8,17 +8,12 @@ module Erb
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
- class_option :singleton, :type => :boolean, :desc => "Supply to skip index view"
-
def create_root_folder
empty_directory File.join("app/views", controller_file_path)
end
def copy_view_files
- views = available_views
- views.delete("index") if options[:singleton]
-
- views.each do |view|
+ available_views.each do |view|
filename = filename_with_extensions(view)
template filename, File.join("app/views", controller_file_path, filename)
end
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
index 9b83207b3f..d12b2ff0e5 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
@@ -1,10 +1,10 @@
-<%%= form_for(@<%= singular_name %>) do |f| %>
- <%% if @<%= singular_name %>.errors.any? %>
+<%%= form_for(@<%= singular_table_name %>) do |f| %>
+ <%% if @<%= singular_table_name %>.errors.any? %>
<div id="error_explanation">
- <h2><%%= pluralize(@<%= singular_name %>.errors.count, "error") %> prohibited this <%= singular_name %> from being saved:</h2>
+ <h2><%%= pluralize(@<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
<ul>
- <%% @<%= singular_name %>.errors.full_messages.each do |msg| %>
+ <%% @<%= singular_table_name %>.errors.full_messages.each do |msg| %>
<li><%%= msg %></li>
<%% end %>
</ul>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
index 5bc507ffc8..e58b9fbd08 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
@@ -1,6 +1,6 @@
-<h1>Editing <%= singular_name %></h1>
+<h1>Editing <%= singular_table_name %></h1>
<%%= render 'form' %>
-<%%= link_to 'Show', @<%= singular_name %> %> |
-<%%= link_to 'Back', <%= plural_name %>_path %>
+<%%= link_to 'Show', @<%= singular_table_name %> %> |
+<%%= link_to 'Back', <%= index_helper %>_path %>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
index d30d306d42..4c46db4d67 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
@@ -1,4 +1,4 @@
-<h1>Listing <%= plural_name %></h1>
+<h1>Listing <%= plural_table_name %></h1>
<table>
<tr>
@@ -10,18 +10,18 @@
<th></th>
</tr>
-<%% @<%= plural_name %>.each do |<%= singular_name %>| %>
+<%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
<tr>
<% for attribute in attributes -%>
- <td><%%= <%= singular_name %>.<%= attribute.name %> %></td>
+ <td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td>
<% end -%>
- <td><%%= link_to 'Show', <%= singular_name %> %></td>
- <td><%%= link_to 'Edit', edit_<%= singular_name %>_path(<%= singular_name %>) %></td>
- <td><%%= link_to 'Destroy', <%= singular_name %>, :confirm => 'Are you sure?', :method => :delete %></td>
+ <td><%%= link_to 'Show', <%= singular_table_name %> %></td>
+ <td><%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>) %></td>
+ <td><%%= link_to 'Destroy', <%= singular_table_name %>, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<%% end %>
</table>
<br />
-<%%= link_to 'New <%= human_name %>', new_<%= singular_name %>_path %>
+<%%= link_to 'New <%= human_name %>', new_<%= singular_table_name %>_path %>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
index 9a1c489331..02ae4d015e 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
@@ -1,5 +1,5 @@
-<h1>New <%= singular_name %></h1>
+<h1>New <%= singular_table_name %></h1>
<%%= render 'form' %>
-<%%= link_to 'Back', <%= plural_name %>_path %>
+<%%= link_to 'Back', <%= index_helper %>_path %>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
index 6b3518717a..c0e5ccff1e 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
@@ -3,10 +3,10 @@
<% for attribute in attributes -%>
<p>
<b><%= attribute.human_name %>:</b>
- <%%= @<%= singular_name %>.<%= attribute.name %> %>
+ <%%= @<%= singular_table_name %>.<%= attribute.name %> %>
</p>
<% end -%>
-<%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> |
-<%%= link_to 'Back', <%= plural_name %>_path %>
+<%%= link_to 'Edit', edit_<%= singular_table_name %>_path(@<%= singular_table_name %>) %> |
+<%%= link_to 'Back', <%= index_helper %>_path %>
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index 8d1dfbd947..44f831e6f3 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -46,6 +46,30 @@ module Rails
end
end
+ def uncountable?
+ singular_name == plural_name
+ end
+
+ def index_helper
+ uncountable? ? "#{plural_table_name}_index" : plural_table_name
+ end
+
+ def singular_table_name
+ @singular_table_name ||= table_name.singularize
+ end
+
+ def plural_table_name
+ @plural_table_name ||= table_name.pluralize
+ end
+
+ def plural_file_name
+ @plural_file_name ||= file_name.pluralize
+ end
+
+ def route_url
+ @route_url ||= class_path.collect{|dname| "/" + dname }.join('') + "/" + plural_file_name
+ end
+
# Tries to retrieve the application name or simple return application.
def application_name
if defined?(Rails) && Rails.application
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index 0b922a89c0..a108968b97 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -32,8 +32,9 @@ gem '<%= gem_for_database %>'<% if require_for_database %>, :require => '<%= req
# gem 'sqlite3-ruby', :require => 'sqlite3'
# gem 'aws-s3', :require => 'aws/s3'
-# Bundle gems for certain environments:
-# gem 'rspec', :group => :test
-# group :test do
+# Bundle gems for the local environment. Make sure to
+# put test-only gems in this group so their generators
+# and rake tasks are available in development mode:
+# group :development, :test do
# gem 'webrat'
# end
diff --git a/railties/lib/rails/generators/rails/app/templates/README b/railties/lib/rails/generators/rails/app/templates/README
index 9ec6db6d71..e2764dee03 100644
--- a/railties/lib/rails/generators/rails/app/templates/README
+++ b/railties/lib/rails/generators/rails/app/templates/README
@@ -37,7 +37,7 @@ link:files/vendor/rails/actionpack/README.html.
3. Go to http://localhost:3000/ and you'll see:
"Welcome aboard: You're riding the Rails!"
-4. Follow the guidelines to start developing your application. You can find
+4. Follow the guidelines to start developing your application. You can find
the following resources handy:
* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
@@ -71,13 +71,13 @@ The result will be a message in your log file along the lines of:
More information on how to use the logger is at http://www.ruby-doc.org/core/
-Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
+Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
several books available online as well:
* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
-These two books will bring you up to speed on the Ruby language and also on
+These two books will bring you up to speed on the Ruby language and also on
programming in general.
@@ -199,7 +199,7 @@ app/controllers
ApplicationController which itself descends from ActionController::Base.
app/models
- Holds models that should be named like post.rb. Models descend from
+ Holds models that should be named like post.rb. Models descend from
ActiveRecord::Base by default.
app/views
diff --git a/railties/lib/rails/generators/rails/app/templates/Rakefile b/railties/lib/rails/generators/rails/app/templates/Rakefile
index 13f1f9fa41..13f1f9fa41 100755..100644
--- a/railties/lib/rails/generators/rails/app/templates/Rakefile
+++ b/railties/lib/rails/generators/rails/app/templates/Rakefile
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index 0066e2b0c2..031466cb86 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -22,7 +22,7 @@ module <%= app_const_base %>
# -- all .rb files in that directory are automatically loaded.
# Add additional load paths for your own custom dirs
- # config.load_paths += %W( #{config.root}/extras )
+ # config.autoload_paths += %W( #{config.root}/extras )
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
index 2784a949fb..df5ef33064 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
@@ -32,40 +32,52 @@
# please refer to the latest documents at http://rubyforge.org/docman/?group_id=2361
development:
- adapter: ibm_db
- username: db2inst1
+ adapter: ibm_db
+ username: db2inst1
password:
- database: <%= app_name[0,4] %>_dev
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
+ database: <%= app_name[0,4] %>_dev
+ #schema: db2inst1
+ #host: localhost
+ #port: 50000
+ #account: my_account
+ #app_user: my_app_user
#application: my_application
#workstation: my_workstation
+ #security: SSL
+ #timeout: 10
+ #authentication: SERVER
+ #parameterized: false
test:
- adapter: ibm_db
- username: db2inst1
+ adapter: ibm_db
+ username: db2inst1
password:
- database: <%= app_name[0,4] %>_tst
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
+ database: <%= app_name[0,4] %>_tst
+ #schema: db2inst1
+ #host: localhost
+ #port: 50000
+ #account: my_account
+ #app_user: my_app_user
#application: my_application
#workstation: my_workstation
+ #security: SSL
+ #timeout: 10
+ #authentication: SERVER
+ #parameterized: false
production:
- adapter: ibm_db
- username: db2inst1
+ adapter: ibm_db
+ username: db2inst1
password:
- database: <%= app_name[0,8] %>
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
+ database: <%= app_name[0,8] %>
+ #schema: db2inst1
+ #host: localhost
+ #port: 50000
+ #account: my_account
+ #app_user: my_app_user
#application: my_application
#workstation: my_workstation
+ #security: SSL
+ #timeout: 10
+ #authentication: SERVER
+ #parameterized: false \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
index 6bf2f7b1fd..ffc8a0a8cb 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
@@ -52,7 +52,7 @@ production:
database: <%= app_name %>_production
pool: 5
username: root
- password:
+ password:
<% if mysql_socket -%>
socket: <%= mysql_socket %>
<% else -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
index a1883f6256..f99ee937f3 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
@@ -36,4 +36,4 @@ production:
adapter: oracle
database: <%= app_name %>_production
username: <%= app_name %>
- password:
+ password:
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
index f0e917dd96..99758dfcf7 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
@@ -16,4 +16,7 @@
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
+
+ # Print deprecation notices to the Rails logger
+ config.active_support.deprecation = :log
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index b9fb13b640..500fc4d860 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
@@ -43,4 +43,7 @@
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true
+
+ # Send deprecation notices to registered listeners
+ config.active_support.deprecation = :notify
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
index beb28e2229..26cdef071a 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
@@ -29,4 +29,7 @@
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
+
+ # Print deprecation notices to the stderr
+ config.active_support.deprecation = :stderr
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb
index d531b8bb82..9e8b0131f8 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb
@@ -1,6 +1,6 @@
# Be sure to restart your server when you modify this file.
-# Add new inflection rules using the following format
+# Add new inflection rules using the following format
# (all these examples are active by default):
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt
index c2fa31aadb..22aa576f5d 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt
@@ -2,6 +2,6 @@
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
-# Make sure the secret is at least 30 characters and all random,
+# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Rails.application.config.secret_token = '<%= app_secret %>'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/routes.rb b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
index d6c0365c04..d42cf3bfdf 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
@@ -1,4 +1,4 @@
-<%= app_const %>.routes.draw do |map|
+<%= app_const %>.routes.draw do
# The priority is based upon order of creation:
# first created -> highest priority.
diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js
index c5fa02ae35..4283ed8982 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js
@@ -1,87 +1,148 @@
-document.observe("dom:loaded", function() {
+(function() {
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ function isEventSupported(eventName) {
+ var el = document.createElement('div');
+ eventName = 'on' + eventName;
+ var isSupported = (eventName in el);
+ if (!isSupported) {
+ el.setAttribute(eventName, 'return;');
+ isSupported = typeof el[eventName] == 'function';
+ }
+ el = null;
+ return isSupported;
+ }
+
+ function isForm(element) {
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
+ }
+
+ function isInput(element) {
+ if (Object.isElement(element)) {
+ var name = element.nodeName.toUpperCase()
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
+ }
+ else return false
+ }
+
+ var submitBubbles = isEventSupported('submit'),
+ changeBubbles = isEventSupported('change')
+
+ if (!submitBubbles || !changeBubbles) {
+ // augment the Event.Handler class to observe custom events when needed
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
+ function(init, element, eventName, selector, callback) {
+ init(element, eventName, selector, callback)
+ // is the handler being attached to an element that doesn't support this event?
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
+ // "submit" => "emulated:submit"
+ this.eventName = 'emulated:' + this.eventName
+ }
+ }
+ )
+ }
+
+ if (!submitBubbles) {
+ // discover forms on the page by observing focus events which always bubble
+ document.on('focusin', 'form', function(focusEvent, form) {
+ // special handler for the real "submit" event (one-time operation)
+ if (!form.retrieve('emulated:submit')) {
+ form.on('submit', function(submitEvent) {
+ var emulated = form.fire('emulated:submit', submitEvent, true)
+ // if custom event received preventDefault, cancel the real one too
+ if (emulated.returnValue === false) submitEvent.preventDefault()
+ })
+ form.store('emulated:submit', true)
+ }
+ })
+ }
+
+ if (!changeBubbles) {
+ // discover form inputs on the page
+ document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
+ // special handler for real "change" events
+ if (!input.retrieve('emulated:change')) {
+ input.on('change', function(changeEvent) {
+ input.fire('emulated:change', changeEvent, true)
+ })
+ input.store('emulated:change', true)
+ }
+ })
+ }
+
function handleRemote(element) {
var method, url, params;
+ var event = element.fire("ajax:before");
+ if (event.stopped) return false;
+
if (element.tagName.toLowerCase() === 'form') {
method = element.readAttribute('method') || 'post';
url = element.readAttribute('action');
- params = element.serialize(true);
+ params = element.serialize();
} else {
method = element.readAttribute('data-method') || 'get';
url = element.readAttribute('href');
params = {};
}
- var event = element.fire("ajax:before");
- if (event.stopped) return false;
-
new Ajax.Request(url, {
method: method,
parameters: params,
- asynchronous: true,
evalScripts: true,
- onLoading: function(request) { element.fire("ajax:loading", {request: request}); },
- onLoaded: function(request) { element.fire("ajax:loaded", {request: request}); },
- onInteractive: function(request) { element.fire("ajax:interactive", {request: request}); },
- onComplete: function(request) { element.fire("ajax:complete", {request: request}); },
- onSuccess: function(request) { element.fire("ajax:success", {request: request}); },
- onFailure: function(request) { element.fire("ajax:failure", {request: request}); }
+ onComplete: function(request) { element.fire("ajax:complete", request); },
+ onSuccess: function(request) { element.fire("ajax:success", request); },
+ onFailure: function(request) { element.fire("ajax:failure", request); }
});
element.fire("ajax:after");
}
function handleMethod(element) {
- var method, url, token_name, token;
-
- method = element.readAttribute('data-method');
- url = element.readAttribute('href');
- csrf_param = $$('meta[name=csrf-param]').first();
- csrf_token = $$('meta[name=csrf-token]').first();
+ var method = element.readAttribute('data-method'),
+ url = element.readAttribute('href'),
+ csrf_param = $$('meta[name=csrf-param]')[0],
+ csrf_token = $$('meta[name=csrf-token]')[0];
var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
- element.parentNode.appendChild(form);
+ element.parentNode.insert(form);
- if (method != 'post') {
+ if (method !== 'post') {
var field = new Element('input', { type: 'hidden', name: '_method', value: method });
- form.appendChild(field);
+ form.insert(field);
}
if (csrf_param) {
- var param = csrf_param.readAttribute('content');
- var token = csrf_token.readAttribute('content');
- var field = new Element('input', { type: 'hidden', name: param, value: token });
- form.appendChild(field);
+ var param = csrf_param.readAttribute('content'),
+ token = csrf_token.readAttribute('content'),
+ field = new Element('input', { type: 'hidden', name: param, value: token });
+ form.insert(field);
}
form.submit();
}
- $(document.body).observe("click", function(event) {
- var message = event.findElement().readAttribute('data-confirm');
- if (message && !confirm(message)) {
- event.stop();
- return false;
- }
- var element = event.findElement("a[data-remote]");
- if (element) {
- handleRemote(element);
- event.stop();
- return true;
- }
+ document.on("click", "*[data-confirm]", function(event, element) {
+ var message = element.readAttribute('data-confirm');
+ if (!confirm(message)) event.stop();
+ });
- var element = event.findElement("a[data-method]");
- if (element) {
- handleMethod(element);
- event.stop();
- return true;
- }
+ document.on("click", "a[data-remote]", function(event, element) {
+ if (event.stopped) return;
+ handleRemote(element);
+ event.stop();
+ });
+
+ document.on("click", "a[data-method]", function(event, element) {
+ if (event.stopped) return;
+ handleMethod(element);
+ event.stop();
});
- // TODO: I don't think submit bubbles in IE
- $(document.body).observe("submit", function(event) {
+ document.on("submit", function(event) {
var element = event.findElement(),
message = element.readAttribute('data-confirm');
if (message && !confirm(message)) {
@@ -103,16 +164,12 @@ document.observe("dom:loaded", function() {
}
});
- $(document.body).observe("ajax:after", function(event) {
- var element = event.findElement();
-
- if (element.tagName.toLowerCase() === 'form') {
- var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
- inputs.each(function(input) {
- input.value = input.readAttribute('data-original-value');
- input.writeAttribute('data-original-value', null);
- input.disabled = false;
- });
- }
+ document.on("ajax:after", "form", function(event, element) {
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
+ inputs.each(function(input) {
+ input.value = input.readAttribute('data-original-value');
+ input.removeAttribute('data-original-value');
+ input.disabled = false;
+ });
});
-}); \ No newline at end of file
+})();
diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE
index db98a2dd1b..67f76aad01 100644
--- a/railties/lib/rails/generators/rails/model/USAGE
+++ b/railties/lib/rails/generators/rails/model/USAGE
@@ -40,6 +40,6 @@ Examples:
Module: app/models/admin.rb
Model: app/models/admin/account.rb
Test: test/unit/admin/account_test.rb
- Fixtures: test/fixtures/admin_accounts.yml
+ Fixtures: test/fixtures/admin/accounts.yml
Migration: db/migrate/XXX_add_admin_accounts.rb
diff --git a/railties/lib/rails/generators/rails/resource/resource_generator.rb b/railties/lib/rails/generators/rails/resource/resource_generator.rb
index 8a46708009..fc070026d6 100644
--- a/railties/lib/rails/generators/rails/resource/resource_generator.rb
+++ b/railties/lib/rails/generators/rails/resource/resource_generator.rb
@@ -14,23 +14,13 @@ module Rails
class_option :actions, :type => :array, :banner => "ACTION ACTION", :default => [],
:desc => "Actions for the resource controller"
- class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
-
def add_resource_route
return if options[:actions].present?
- route "resource#{:s unless options[:singleton]} :#{pluralize?(file_name)}"
+ route_config = class_path.collect{|namespace| "namespace :#{namespace} do " }.join(" ")
+ route_config << "resources :#{file_name.pluralize}"
+ route_config << " end" * class_path.size
+ route route_config
end
-
- protected
-
- def pluralize?(name)
- if options[:singleton]
- name
- else
- name.pluralize
- end
- end
-
end
end
end
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
index 49af2974cd..2271c6f9c1 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
@@ -10,8 +10,6 @@ module Rails
class_option :orm, :banner => "NAME", :type => :string, :required => true,
:desc => "ORM to generate the controller for"
- class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
-
def create_controller_files
template 'controller.rb', File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb")
end
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
index bbdce669dc..b21340f755 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
@@ -1,53 +1,51 @@
class <%= controller_class_name %>Controller < ApplicationController
-<% unless options[:singleton] -%>
- # GET /<%= table_name %>
- # GET /<%= table_name %>.xml
+ # GET <%= route_url %>
+ # GET <%= route_url %>.xml
def index
- @<%= table_name %> = <%= orm_class.all(class_name) %>
+ @<%= plural_table_name %> = <%= orm_class.all(class_name) %>
respond_to do |format|
format.html # index.html.erb
- format.xml { render :xml => @<%= table_name %> }
+ format.xml { render :xml => @<%= plural_table_name %> }
end
end
-<% end -%>
- # GET /<%= table_name %>/1
- # GET /<%= table_name %>/1.xml
+ # GET <%= route_url %>/1
+ # GET <%= route_url %>/1.xml
def show
- @<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
respond_to do |format|
format.html # show.html.erb
- format.xml { render :xml => @<%= file_name %> }
+ format.xml { render :xml => @<%= singular_table_name %> }
end
end
- # GET /<%= table_name %>/new
- # GET /<%= table_name %>/new.xml
+ # GET <%= route_url %>/new
+ # GET <%= route_url %>/new.xml
def new
- @<%= file_name %> = <%= orm_class.build(class_name) %>
+ @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
respond_to do |format|
format.html # new.html.erb
- format.xml { render :xml => @<%= file_name %> }
+ format.xml { render :xml => @<%= singular_table_name %> }
end
end
- # GET /<%= table_name %>/1/edit
+ # GET <%= route_url %>/1/edit
def edit
- @<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
end
- # POST /<%= table_name %>
- # POST /<%= table_name %>.xml
+ # POST <%= route_url %>
+ # POST <%= route_url %>.xml
def create
- @<%= file_name %> = <%= orm_class.build(class_name, "params[:#{file_name}]") %>
+ @<%= singular_table_name %> = <%= orm_class.build(class_name, "params[:#{singular_table_name}]") %>
respond_to do |format|
if @<%= orm_instance.save %>
- format.html { redirect_to(@<%= file_name %>, :notice => '<%= human_name %> was successfully created.') }
- format.xml { render :xml => @<%= file_name %>, :status => :created, :location => @<%= file_name %> }
+ format.html { redirect_to(@<%= singular_table_name %>, :notice => '<%= human_name %> was successfully created.') }
+ format.xml { render :xml => @<%= singular_table_name %>, :status => :created, :location => @<%= singular_table_name %> }
else
format.html { render :action => "new" }
format.xml { render :xml => @<%= orm_instance.errors %>, :status => :unprocessable_entity }
@@ -55,14 +53,14 @@ class <%= controller_class_name %>Controller < ApplicationController
end
end
- # PUT /<%= table_name %>/1
- # PUT /<%= table_name %>/1.xml
+ # PUT <%= route_url %>/1
+ # PUT <%= route_url %>/1.xml
def update
- @<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
respond_to do |format|
- if @<%= orm_instance.update_attributes("params[:#{file_name}]") %>
- format.html { redirect_to(@<%= file_name %>, :notice => '<%= human_name %> was successfully updated.') }
+ if @<%= orm_instance.update_attributes("params[:#{singular_table_name}]") %>
+ format.html { redirect_to(@<%= singular_table_name %>, :notice => '<%= human_name %> was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
@@ -71,14 +69,14 @@ class <%= controller_class_name %>Controller < ApplicationController
end
end
- # DELETE /<%= table_name %>/1
- # DELETE /<%= table_name %>/1.xml
+ # DELETE <%= route_url %>/1
+ # DELETE <%= route_url %>/1.xml
def destroy
- @<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
@<%= orm_instance.destroy %>
respond_to do |format|
- format.html { redirect_to(<%= table_name %>_url) }
+ format.html { redirect_to(<%= index_helper %>_url) }
format.xml { head :ok }
end
end
diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb
index 3a98a8f9c1..829f4b200a 100644
--- a/railties/lib/rails/generators/resource_helpers.rb
+++ b/railties/lib/rails/generators/resource_helpers.rb
@@ -72,7 +72,7 @@ module Rails
end
# Initialize ORM::Generators::ActiveModel to access instance methods.
- def orm_instance(name=file_name)
+ def orm_instance(name=singular_table_name)
@orm_instance ||= @orm_class.new(name)
end
end
diff --git a/railties/lib/rails/generators/test_unit/model/model_generator.rb b/railties/lib/rails/generators/test_unit/model/model_generator.rb
index 609b815683..c1dd535dd3 100644
--- a/railties/lib/rails/generators/test_unit/model/model_generator.rb
+++ b/railties/lib/rails/generators/test_unit/model/model_generator.rb
@@ -16,7 +16,7 @@ module TestUnit
def create_fixture_file
if options[:fixture] && options[:fixture_replacement].nil?
- template 'fixtures.yml', File.join('test/fixtures', "#{table_name}.yml")
+ template 'fixtures.yml', File.join('test/fixtures', class_path, "#{plural_file_name}.yml")
end
end
end
diff --git a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
index c0315c7fe6..f7e907a017 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
@@ -6,7 +6,6 @@ module TestUnit
class ScaffoldGenerator < Base
include Rails::Generators::ResourceHelpers
- class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
check_class_collision :suffix => "ControllerTest"
def create_test_files
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
index 4f8ddbffcf..f23e495450 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
@@ -2,50 +2,48 @@ require 'test_helper'
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
setup do
- @<%= file_name %> = <%= table_name %>(:one)
+ @<%= singular_table_name %> = <%= table_name %>(:one)
end
-<% unless options[:singleton] -%>
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:<%= table_name %>)
end
-<% end -%>
test "should get new" do
get :new
assert_response :success
end
- test "should create <%= file_name %>" do
+ test "should create <%= singular_table_name %>" do
assert_difference('<%= class_name %>.count') do
- post :create, :<%= file_name %> => @<%= file_name %>.attributes
+ post :create, :<%= singular_table_name %> => @<%= singular_table_name %>.attributes
end
- assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
+ assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
end
- test "should show <%= file_name %>" do
- get :show, :id => @<%= file_name %>.to_param
+ test "should show <%= singular_table_name %>" do
+ get :show, :id => @<%= singular_table_name %>.to_param
assert_response :success
end
test "should get edit" do
- get :edit, :id => @<%= file_name %>.to_param
+ get :edit, :id => @<%= singular_table_name %>.to_param
assert_response :success
end
- test "should update <%= file_name %>" do
- put :update, :id => @<%= file_name %>.to_param, :<%= file_name %> => @<%= file_name %>.attributes
- assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
+ test "should update <%= singular_table_name %>" do
+ put :update, :id => @<%= singular_table_name %>.to_param, :<%= singular_table_name %> => @<%= singular_table_name %>.attributes
+ assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
end
- test "should destroy <%= file_name %>" do
+ test "should destroy <%= singular_table_name %>" do
assert_difference('<%= class_name %>.count', -1) do
- delete :destroy, :id => @<%= file_name %>.to_param
+ delete :destroy, :id => @<%= singular_table_name %>.to_param
end
- assert_redirected_to <%= table_name %>_path
+ assert_redirected_to <%= index_helper %>_path
end
end
diff --git a/railties/lib/rails/initializable.rb b/railties/lib/rails/initializable.rb
index 9a82e051e7..686a2dc0cb 100644
--- a/railties/lib/rails/initializable.rb
+++ b/railties/lib/rails/initializable.rb
@@ -39,11 +39,6 @@ module Rails
select { |i| i.before == initializer.name || i.name == initializer.after }.each(&block)
end
- def initialize(initializers = [])
- super(initializers)
- replace(tsort)
- end
-
def +(other)
Collection.new(to_a + other.to_a)
end
@@ -51,7 +46,7 @@ module Rails
def run_initializers(*args)
return if instance_variable_defined?(:@ran)
- initializers.each do |initializer|
+ initializers.tsort.each do |initializer|
initializer.run(*args)
end
@ran = true
@@ -63,7 +58,7 @@ module Rails
module ClassMethods
def initializers
- @initializers ||= []
+ @initializers ||= Collection.new
end
def initializers_chain
@@ -84,14 +79,6 @@ module Rails
opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] }
initializers << Initializer.new(name, nil, opts, &blk)
end
-
- def run_initializers(*args)
- return if @ran
- initializers_chain.each do |initializer|
- instance_exec(*args, &initializer.block)
- end
- @ran = true
- end
end
end
-end \ No newline at end of file
+end
diff --git a/railties/lib/rails/log_subscriber.rb b/railties/lib/rails/log_subscriber.rb
deleted file mode 100644
index a30701d4d5..0000000000
--- a/railties/lib/rails/log_subscriber.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-require 'active_support/core_ext/class/inheritable_attributes'
-require 'active_support/notifications'
-
-module Rails
- # Rails::LogSubscriber is an object set to consume ActiveSupport::Notifications
- # on initialization with solely purpose of logging. The log subscriber dispatches
- # notifications to a regirested object based on its given namespace.
- #
- # An example would be Active Record log subscriber responsible for logging queries:
- #
- # module ActiveRecord
- # class Railtie
- # class LogSubscriber < Rails::LogSubscriber
- # def sql(event)
- # "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
- # end
- # end
- # end
- # end
- #
- # It's finally registed as:
- #
- # Rails::LogSubscriber.add :active_record, ActiveRecord::Railtie::LogSubscriber.new
- #
- # So whenever a "sql.active_record" notification arrive to Rails::LogSubscriber,
- # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
- # the sql method.
- #
- # This is useful because it avoids spanning several log subscribers just for logging
- # purposes(which slows down the main thread). Besides of providing a centralized
- # facility on top of Rails.logger.
- #
- # Log subscriber also has some helpers to deal with logging and automatically flushes
- # all logs when the request finishes (via action_dispatch.callback notification).
- class LogSubscriber
- mattr_accessor :colorize_logging
- self.colorize_logging = true
-
- # Embed in a String to clear all previous ANSI sequences.
- CLEAR = "\e[0m"
- BOLD = "\e[1m"
-
- # Colors
- BLACK = "\e[30m"
- RED = "\e[31m"
- GREEN = "\e[32m"
- YELLOW = "\e[33m"
- BLUE = "\e[34m"
- MAGENTA = "\e[35m"
- CYAN = "\e[36m"
- WHITE = "\e[37m"
-
- def self.add(namespace, log_subscriber, notifier = ActiveSupport::Notifications)
- log_subscribers << log_subscriber
- @flushable_loggers = nil
-
- log_subscriber.public_methods(false).each do |event|
- notifier.subscribe("#{event}.#{namespace}") do |*args|
- next if log_subscriber.logger.nil?
-
- begin
- log_subscriber.send(event, ActiveSupport::Notifications::Event.new(*args))
- rescue Exception => e
- Rails.logger.error "Could not log #{args[0].inspect} event. #{e.class}: #{e.message}"
- end
- end
- end
- end
-
- def self.log_subscribers
- @log_subscribers ||= []
- end
-
- def self.flushable_loggers
- @flushable_loggers ||= begin
- loggers = log_subscribers.map(&:logger)
- loggers.uniq!
- loggers.select { |l| l.respond_to?(:flush) }
- end
- end
-
- # Flush all log_subscribers' logger.
- def self.flush_all!
- flushable_loggers.each(&:flush)
- end
-
- # By default, we use the Rails.logger for logging.
- def logger
- Rails.logger
- end
-
- protected
-
- %w(info debug warn error fatal unknown).each do |level|
- class_eval <<-METHOD, __FILE__, __LINE__ + 1
- def #{level}(*args, &block)
- return unless logger
- logger.#{level}(*args, &block)
- end
- METHOD
- end
-
- # Set color by using a string or one of the defined constants. If a third
- # option is set to true, it also adds bold to the string. This is based
- # on Highline implementation and it automatically appends CLEAR to the end
- # of the returned String.
- #
- def color(text, color, bold=false)
- return text unless colorize_logging
- color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
- bold = bold ? BOLD : ""
- "#{bold}#{color}#{text}#{CLEAR}"
- end
- end
-end
diff --git a/railties/lib/rails/log_subscriber/test_helper.rb b/railties/lib/rails/log_subscriber/test_helper.rb
deleted file mode 100644
index 9b7b0738cd..0000000000
--- a/railties/lib/rails/log_subscriber/test_helper.rb
+++ /dev/null
@@ -1,97 +0,0 @@
-require 'rails/log_subscriber'
-
-module Rails
- class LogSubscriber
- # Provides some helpers to deal with testing log subscribers by setting up
- # notifications. Take for instance Active Record subscriber tests:
- #
- # class SyncLogSubscriberTest < ActiveSupport::TestCase
- # include Rails::LogSubscriber::TestHelper
- # Rails::LogSubscriber.add(:active_record, ActiveRecord::Railties::LogSubscriber.new)
- #
- # def test_basic_query_logging
- # Developer.all
- # wait
- # assert_equal 1, @logger.logged(:debug).size
- # assert_match /Developer Load/, @logger.logged(:debug).last
- # assert_match /SELECT \* FROM "developers"/, @logger.logged(:debug).last
- # end
- #
- # class SyncLogSubscriberTest < ActiveSupport::TestCase
- # include Rails::LogSubscriber::SyncTestHelper
- # include LogSubscriberTest
- # end
- #
- # class AsyncLogSubscriberTest < ActiveSupport::TestCase
- # include Rails::LogSubscriber::AsyncTestHelper
- # include LogSubscriberTest
- # end
- # end
- #
- # All you need to do is to ensure that your log subscriber is added to Rails::Subscriber,
- # as in the second line of the code above. The test helpers is reponsible for setting
- # up the queue, subscriptions and turning colors in logs off.
- #
- # The messages are available in the @logger instance, which is a logger with limited
- # powers (it actually do not send anything to your output), and you can collect them
- # doing @logger.logged(level), where level is the level used in logging, like info,
- # debug, warn and so on.
- #
- module TestHelper
- def setup
- @logger = MockLogger.new
- @notifier = ActiveSupport::Notifications::Notifier.new(queue)
-
- Rails::LogSubscriber.colorize_logging = false
-
- set_logger(@logger)
- ActiveSupport::Notifications.notifier = @notifier
- end
-
- def teardown
- set_logger(nil)
- ActiveSupport::Notifications.notifier = nil
- end
-
- class MockLogger
- attr_reader :flush_count
-
- def initialize
- @flush_count = 0
- @logged = Hash.new { |h,k| h[k] = [] }
- end
-
- def method_missing(level, message)
- @logged[level] << message
- end
-
- def logged(level)
- @logged[level].compact.map { |l| l.to_s.strip }
- end
-
- def flush
- @flush_count += 1
- end
- end
-
- # Wait notifications to be published.
- def wait
- @notifier.wait
- end
-
- # Overwrite if you use another logger in your log subscriber:
- #
- # def logger
- # ActiveRecord::Base.logger = @logger
- # end
- #
- def set_logger(logger)
- Rails.logger = logger
- end
-
- def queue
- ActiveSupport::Notifications::Fanout.new
- end
- end
- end
-end \ No newline at end of file
diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb
index 1c9e308631..7a65188a9a 100644
--- a/railties/lib/rails/paths.rb
+++ b/railties/lib/rails/paths.rb
@@ -25,9 +25,7 @@ module Rails
def initialize(path)
raise if path.is_a?(Array)
-
@children = {}
-
@path = path
@root = self
@all_paths = []
@@ -38,14 +36,18 @@ module Rails
@all_paths
end
- def load_once
- filter_by(:load_once?)
+ def autoload_once
+ filter_by(:autoload_once?)
end
def eager_load
filter_by(:eager_load?)
end
+ def autoload_paths
+ filter_by(:autoload?)
+ end
+
def load_paths
filter_by(:load_path?)
end
@@ -61,15 +63,17 @@ module Rails
protected
def filter_by(constraint)
- all_paths.map do |path|
+ all = []
+ all_paths.each do |path|
if path.send(constraint)
paths = path.paths
paths -= path.children.values.map { |p| p.send(constraint) ? [] : p.paths }.flatten
- paths
- else
- []
+ all.concat(paths)
end
- end.flatten.uniq.select { |p| File.exists?(p) }
+ end
+ all.uniq!
+ all.reject! { |p| !File.exists?(p) }
+ all
end
end
@@ -80,15 +84,16 @@ module Rails
attr_accessor :glob
def initialize(root, *paths)
- @options = paths.last.is_a?(::Hash) ? paths.pop : {}
+ options = paths.last.is_a?(::Hash) ? paths.pop : {}
@children = {}
@root = root
@paths = paths.flatten
- @glob = @options.delete(:glob)
+ @glob = options[:glob]
- @load_once = @options[:load_once]
- @eager_load = @options[:eager_load]
- @load_path = @options[:load_path] || @eager_load || @load_once
+ autoload_once! if options[:autoload_once]
+ eager_load! if options[:eager_load]
+ autoload! if options[:autoload]
+ load_path! if options[:load_path]
@root.all_paths << self
end
@@ -111,24 +116,30 @@ module Rails
@paths.concat paths
end
- def load_once!
- @load_once = true
- @load_path = true
+ def autoload_once!
+ @autoload_once = true
end
- def load_once?
- @load_once
+ def autoload_once?
+ @autoload_once
end
def eager_load!
@eager_load = true
- @load_path = true
end
def eager_load?
@eager_load
end
+ def autoload!
+ @autoload = true
+ end
+
+ def autoload?
+ @autoload
+ end
+
def load_path!
@load_path = true
end
diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb
index fcdd099135..be229cc9a2 100644
--- a/railties/lib/rails/plugin.rb
+++ b/railties/lib/rails/plugin.rb
@@ -61,6 +61,16 @@ module Rails
@config ||= Engine::Configuration.new
end
+ initializer :handle_lib_autoload, :before => :set_load_path do |app|
+ paths = if app.config.reload_plugins
+ config.autoload_paths
+ else
+ config.autoload_once_paths
+ end
+
+ paths.concat config.paths.lib.to_a
+ end
+
initializer :load_init_rb, :before => :load_config_initializers do |app|
files = %w(rails/init.rb init.rb).map { |path| File.expand_path path, root }
if initrb = files.find { |path| File.file? path }
@@ -77,11 +87,5 @@ module Rails
raise "\"#{name}\" is a Railtie/Engine and cannot be installed as plugin"
end
end
-
- protected
-
- def reloadable?(app)
- app.config.reload_plugins
- end
end
end
diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb
index 73e9af3b41..b3dc1f894c 100644
--- a/railties/lib/rails/rack/logger.rb
+++ b/railties/lib/rails/rack/logger.rb
@@ -1,10 +1,9 @@
-require 'rails/log_subscriber'
require 'active_support/core_ext/time/conversions'
module Rails
module Rack
# Log the request started and flush all loggers after it.
- class Logger < Rails::LogSubscriber
+ class Logger < ActiveSupport::LogSubscriber
def initialize(app)
@app = app
end
@@ -16,20 +15,19 @@ module Rails
after_dispatch(env)
end
- protected
+ protected
- def before_dispatch(env)
- request = ActionDispatch::Request.new(env)
- path = request.fullpath
+ def before_dispatch(env)
+ request = ActionDispatch::Request.new(env)
+ path = request.fullpath
- info "\n\nStarted #{env["REQUEST_METHOD"]} \"#{path}\" " \
- "for #{request.ip} at #{Time.now.to_default_s}"
- end
-
- def after_dispatch(env)
- Rails::LogSubscriber.flush_all!
- end
+ info "\n\nStarted #{env["REQUEST_METHOD"]} \"#{path}\" " \
+ "for #{request.ip} at #{Time.now.to_default_s}"
+ end
+ def after_dispatch(env)
+ ActiveSupport::LogSubscriber.flush_all!
+ end
end
end
end
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index ad776933f2..dbdbfea509 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -114,36 +114,6 @@ module Rails
# end
# end
#
- # == Adding your subscriber
- #
- # Since version 3.0, Rails ships with a notification system which is used for several
- # purposes, including logging. If you are sending notifications in your Railtie, you may
- # want to add a subscriber to consume such notifications for logging purposes.
- #
- # The subscriber is added under the railtie_name namespace and only consumes notifications
- # under the given namespace. For example, let's suppose your railtie is publishing the
- # following "something_expensive" instrumentation:
- #
- # ActiveSupport::Notifications.instrument "my_railtie.something_expensive" do
- # # something expensive
- # end
- #
- # You can log this instrumentation with your own Rails::Subscriber:
- #
- # class MyRailtie::Subscriber < Rails::Subscriber
- # def something_expensive(event)
- # info("Something expensive took %.1fms" % event.duration)
- # end
- # end
- #
- # By registering it:
- #
- # class MyRailtie < Railtie
- # subscriber :my_gem, MyRailtie::Subscriber.new
- # end
- #
- # Take a look in Rails::Subscriber docs for more information.
- #
# == Application, Plugin and Engine
#
# A Rails::Engine is nothing more than a Railtie with some initializers already set.
@@ -176,8 +146,8 @@ module Rails
ActiveSupport::Deprecation.warn "railtie_name is deprecated and has no effect", caller
end
- def log_subscriber(name, log_subscriber)
- Rails::LogSubscriber.add(name, log_subscriber)
+ def log_subscriber(*)
+ ActiveSupport::Deprecation.warn "log_subscriber is deprecated and has no effect", caller
end
def rake_tasks(&blk)
diff --git a/railties/lib/rails/webrick_server.rb b/railties/lib/rails/webrick_server.rb
deleted file mode 100644
index f3b74c28d3..0000000000
--- a/railties/lib/rails/webrick_server.rb
+++ /dev/null
@@ -1,156 +0,0 @@
-# Donated by Florian Gross
-
-require 'webrick'
-require 'cgi'
-require 'stringio'
-require 'dispatcher'
-
-include WEBrick
-
-class CGI #:nodoc:
- def stdinput
- @stdin || $stdin
- end
-
- def env_table
- @env_table || ENV
- end
-
- def initialize(type = "query", table = nil, stdin = nil)
- @env_table, @stdin = table, stdin
-
- if defined?(MOD_RUBY) && !ENV.key?("GATEWAY_INTERFACE")
- Apache.request.setup_cgi_env
- end
-
- extend QueryExtension
- @multipart = false
- if defined?(CGI_PARAMS)
- warn "do not use CGI_PARAMS and CGI_COOKIES"
- @params = CGI_PARAMS.dup
- @cookies = CGI_COOKIES.dup
- else
- initialize_query() # set @params, @cookies
- end
- @output_cookies = nil
- @output_hidden = nil
- end
-end
-
-# A custom dispatch servlet for use with WEBrick. It dispatches requests
-# (using the Rails Dispatcher) to the appropriate controller/action. By default,
-# it restricts WEBrick to a managing a single Rails request at a time, but you
-# can change this behavior by setting ActionController::Base.allow_concurrency
-# to true.
-class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
- # Start the WEBrick server with the given options, mounting the
- # DispatchServlet at <tt>/</tt>.
- def self.dispatch(options = {})
- Socket.do_not_reverse_lookup = true # patch for OS X
-
- params = { :Port => options[:port].to_i,
- :ServerType => options[:server_type],
- :BindAddress => options[:ip] }
- params[:MimeTypes] = options[:mime_types] if options[:mime_types]
-
- server = WEBrick::HTTPServer.new(params)
- server.mount('/', DispatchServlet, options)
-
- trap("INT") { server.shutdown }
- server.start
- end
-
- def initialize(server, options) #:nodoc:
- @server_options = options
- @file_handler = WEBrick::HTTPServlet::FileHandler.new(server, options[:server_root])
- # Change to the Rails.root, since Webrick::Daemon.start does a Dir::cwd("/")
- # OPTIONS['working_directory'] is an absolute path of the Rails.root, set in railties/lib/commands/servers/webrick.rb
- Dir.chdir(OPTIONS['working_directory']) if defined?(OPTIONS) && File.directory?(OPTIONS['working_directory'])
- super
- end
-
- def service(req, res) #:nodoc:
- unless handle_file(req, res)
- unless handle_dispatch(req, res)
- raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- end
- end
-
- def handle_file(req, res) #:nodoc:
- begin
- req = req.dup
- path = req.path.dup
-
- # Add .html if the last path piece has no . in it
- path << '.html' if path != '/' && (%r{(^|/)[^./]+$} =~ path)
- path.gsub!('+', ' ') # Unescape + since FileHandler doesn't do so.
-
- req.instance_variable_set(:@path_info, path) # Set the modified path...
-
- @file_handler.send(:service, req, res)
- return true
- rescue HTTPStatus::PartialContent, HTTPStatus::NotModified => err
- res.set_error(err)
- return true
- rescue => err
- return false
- end
- end
-
- def handle_dispatch(req, res, origin = nil) #:nodoc:
- data = StringIO.new
- Dispatcher.dispatch(
- CGI.new("query", create_env_table(req, origin), StringIO.new(req.body || "")),
- ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS,
- data
- )
-
- header, body = extract_header_and_body(data)
-
- set_charset(header)
- assign_status(res, header)
- res.cookies.concat(header.delete('set-cookie') || [])
- header.each { |key, val| res[key] = val.join(", ") }
-
- res.body = body
- return true
- rescue => err
- p err, err.backtrace
- return false
- end
-
- private
- def create_env_table(req, origin)
- env = req.meta_vars.clone
- env.delete "SCRIPT_NAME"
- env["QUERY_STRING"] = req.request_uri.query
- env["REQUEST_URI"] = origin if origin
- return env
- end
-
- def extract_header_and_body(data)
- data.rewind
- data = data.read
-
- raw_header, body = *data.split(/^[\xd\xa]{2}/on, 2)
- header = WEBrick::HTTPUtils::parse_header(raw_header)
-
- return header, body
- end
-
- def set_charset(header)
- ct = header["content-type"]
- if ct.any? { |x| x =~ /^text\// } && ! ct.any? { |x| x =~ /charset=/ }
- ch = @server_options[:charset] || "UTF-8"
- ct.find { |x| x =~ /^text\// } << ("; charset=" + ch)
- end
- end
-
- def assign_status(res, header)
- if /^(\d+)/ =~ header['status'][0]
- res.status = $1.to_i
- header.delete('status')
- end
- end
-end
diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb
index d04a2aa1f3..a05bae5dcc 100644
--- a/railties/test/abstract_unit.rb
+++ b/railties/test/abstract_unit.rb
@@ -1,5 +1,3 @@
-ORIG_ARGV = ARGV.dup
-
require File.expand_path("../../../load_paths", __FILE__)
require 'stringio'
diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb
index 35ea2729d3..7269a7c5a8 100644
--- a/railties/test/application/initializers/frameworks_test.rb
+++ b/railties/test/application/initializers/frameworks_test.rb
@@ -28,8 +28,10 @@ module ApplicationTests
RUBY
require "#{app_path}/config/environment"
- ActionController::Base.view_paths.include?(File.expand_path("app/views", app_path))
- ActionMailer::Base.view_paths.include?(File.expand_path("app/views", app_path))
+
+ expanded_path = File.expand_path("app/views", app_path)
+ assert_equal ActionController::Base.view_paths[0].to_s, expanded_path
+ assert_equal ActionMailer::Base.view_paths[0].to_s, expanded_path
end
test "allows me to configure default url options for ActionMailer" do
@@ -40,7 +42,7 @@ module ApplicationTests
RUBY
require "#{app_path}/config/environment"
- assert "test.rails", ActionMailer::Base.default_url_options[:host]
+ assert_equal "test.rails", ActionMailer::Base.default_url_options[:host]
end
# AS
@@ -57,7 +59,7 @@ module ApplicationTests
Dir.chdir("#{app_path}/app") do
require "#{app_path}/config/environment"
- assert_raises(NoMethodError) { [1,2,3].sample }
+ assert_raises(NoMethodError) { [1,2,3].forty_two }
end
end
diff --git a/railties/test/application/initializers/i18n_test.rb b/railties/test/application/initializers/i18n_test.rb
index 99b2d86013..a1fcba3310 100644
--- a/railties/test/application/initializers/i18n_test.rb
+++ b/railties/test/application/initializers/i18n_test.rb
@@ -8,48 +8,143 @@ module ApplicationTests
build_app
boot_rails
FileUtils.rm_rf "#{app_path}/config/environments"
+ require "rails/all"
end
- # i18n
+ def load_app
+ require "#{app_path}/config/environment"
+ end
+
+ def app
+ @app ||= Rails::Application
+ end
+
+ def assert_fallbacks(fallbacks)
+ fallbacks.each do |locale, expected|
+ actual = I18n.fallbacks[locale]
+ assert_equal expected, actual, "expected fallbacks for #{locale.inspect} to be #{expected.inspect}, but were #{actual.inspect}"
+ end
+ end
+
+ def assert_no_fallbacks
+ assert !I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
+ end
+
+ # Locales
test "setting another default locale" do
add_to_config <<-RUBY
- config.root = "#{app_path}"
config.i18n.default_locale = :de
RUBY
- require "#{app_path}/config/environment"
+ load_app
assert_equal :de, I18n.default_locale
end
+ # Load paths
test "no config locales dir present should return empty load path" do
FileUtils.rm_rf "#{app_path}/config/locales"
- add_to_config <<-RUBY
- config.root = "#{app_path}"
- RUBY
- require "#{app_path}/config/environment"
-
+ load_app
assert_equal [], Rails.application.config.i18n.load_path
end
- test "config locales dir present should be added to load path" do
+ test "locale files should be added to the load path" do
+ app_file "config/another_locale.yml", ""
+
add_to_config <<-RUBY
- config.root = "#{app_path}"
+ config.i18n.load_path << config.root.join("config/another_locale.yml").to_s
RUBY
- require "#{app_path}/config/environment"
- assert_equal ["#{app_path}/config/locales/en.yml"], Rails.application.config.i18n.load_path
+ load_app
+ assert_equal [
+ "#{app_path}/config/locales/en.yml", "#{app_path}/config/another_locale.yml"
+ ], Rails.application.config.i18n.load_path
+
+ assert I18n.load_path.include?("#{app_path}/config/locales/en.yml")
+ assert I18n.load_path.include?("#{app_path}/config/another_locale.yml")
end
- test "config defaults should be added with config settings" do
+ test "locales are reloaded if they change between requests" do
add_to_config <<-RUBY
- config.root = "#{app_path}"
- config.i18n.load_path << "my/other/locale.yml"
+ config.cache_classes = false
RUBY
- require "#{app_path}/config/environment"
- assert_equal [
- "#{app_path}/config/locales/en.yml", "my/other/locale.yml"
- ], Rails.application.config.i18n.load_path
+ app_file "config/locales/en.yml", <<-YAML
+en:
+ foo: "1"
+ YAML
+
+ app_file 'config/routes.rb', <<-RUBY
+ AppTemplate::Application.routes.draw do |map|
+ match '/i18n', :to => lambda { |env| [200, {}, [I18n.t(:foo)]] }
+ end
+ RUBY
+
+ require 'rack/test'
+ extend Rack::Test::Methods
+ load_app
+
+ get "/i18n"
+ assert_equal "1", last_response.body
+
+ app_file "config/locales/en.yml", <<-YAML
+en:
+ foo: "2"
+ YAML
+
+ get "/i18n"
+ assert_equal "2", last_response.body
+ end
+
+ # Fallbacks
+ test "not using config.i18n.fallbacks does not initialize I18n.fallbacks" do
+ I18n.backend = Class.new { include I18n::Backend::Base }.new
+ load_app
+ assert_no_fallbacks
+ end
+
+ test "config.i18n.fallbacks = true initializes I18n.fallbacks with default settings" do
+ I18n::Railtie.config.i18n.fallbacks = true
+ load_app
+ assert I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
+ assert_fallbacks :de => [:de, :en]
+ end
+
+ test "config.i18n.fallbacks = true initializes I18n.fallbacks with default settings even when backend changes" do
+ I18n::Railtie.config.i18n.fallbacks = true
+ I18n::Railtie.config.i18n.backend = Class.new { include I18n::Backend::Base }.new
+ load_app
+ assert I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
+ assert_fallbacks :de => [:de, :en]
+ end
+
+ test "config.i18n.fallbacks.defaults = [:'en-US'] initializes fallbacks with en-US as a fallback default" do
+ I18n::Railtie.config.i18n.fallbacks.defaults = [:'en-US']
+ load_app
+ assert_fallbacks :de => [:de, :'en-US', :en]
+ end
+
+ test "config.i18n.fallbacks.map = { :ca => :'es-ES' } initializes fallbacks with a mapping ca => es-ES" do
+ I18n::Railtie.config.i18n.fallbacks.map = { :ca => :'es-ES' }
+ load_app
+ assert_fallbacks :ca => [:ca, :"es-ES", :es, :en]
+ end
+
+ test "[shortcut] config.i18n.fallbacks = [:'en-US'] initializes fallbacks with en-US as a fallback default" do
+ I18n::Railtie.config.i18n.fallbacks = [:'en-US']
+ load_app
+ assert_fallbacks :de => [:de, :'en-US', :en]
+ end
+
+ test "[shortcut] config.i18n.fallbacks = [{ :ca => :'es-ES' }] initializes fallbacks with a mapping de-AT => de-DE" do
+ I18n::Railtie.config.i18n.fallbacks.map = { :ca => :'es-ES' }
+ load_app
+ assert_fallbacks :ca => [:ca, :"es-ES", :es, :en]
+ end
+
+ test "[shortcut] config.i18n.fallbacks = [:'en-US', { :ca => :'es-ES' }] initializes fallbacks with the given arguments" do
+ I18n::Railtie.config.i18n.fallbacks = [:'en-US', { :ca => :'es-ES' }]
+ load_app
+ assert_fallbacks :ca => [:ca, :"es-ES", :es, :'en-US', :en]
end
end
end \ No newline at end of file
diff --git a/railties/test/application/initializers/load_path_test.rb b/railties/test/application/initializers/load_path_test.rb
index d31915e129..714d62311d 100644
--- a/railties/test/application/initializers/load_path_test.rb
+++ b/railties/test/application/initializers/load_path_test.rb
@@ -19,7 +19,7 @@ module ApplicationTests
assert $:.include?("#{app_path}/app/models")
end
- test "initializing an application adds lib path on inheritance hook" do
+ test "initializing an application allows to load code on lib path inside application class definitation" do
app_file "lib/foo.rb", <<-RUBY
module Foo; end
RUBY
diff --git a/railties/test/application/loading_test.rb b/railties/test/application/loading_test.rb
new file mode 100644
index 0000000000..340ce67511
--- /dev/null
+++ b/railties/test/application/loading_test.rb
@@ -0,0 +1,86 @@
+require 'isolation/abstract_unit'
+
+class LoadingTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ build_app
+ boot_rails
+ end
+
+ def app
+ @app ||= Rails.application
+ end
+
+ def test_constants_in_app_are_autoloaded
+ app_file "app/models/post.rb", <<-MODEL
+ class Post < ActiveRecord::Base
+ validates_acceptance_of :title, :accept => "omg"
+ end
+ MODEL
+
+ require "#{rails_root}/config/environment"
+ setup_ar!
+
+ p = Post.create(:title => 'omg')
+ assert_equal 1, Post.count
+ assert_equal 'omg', p.title
+ p = Post.first
+ assert_equal 'omg', p.title
+ end
+
+ def test_models_without_table_do_not_panic_on_scope_definitions_when_loaded
+ app_file "app/models/user.rb", <<-MODEL
+ class User < ActiveRecord::Base
+ default_scope where(:published => true)
+ end
+ MODEL
+
+ require "#{rails_root}/config/environment"
+ setup_ar!
+
+ User
+ end
+
+ def test_descendants_are_cleaned_on_each_request_without_cache_classes
+ add_to_config <<-RUBY
+ config.cache_classes = false
+ RUBY
+
+ app_file "app/models/post.rb", <<-MODEL
+ class Post < ActiveRecord::Base
+ end
+ MODEL
+
+ app_file 'config/routes.rb', <<-RUBY
+ AppTemplate::Application.routes.draw do |map|
+ match '/load', :to => lambda { |env| [200, {}, Post.all] }
+ match '/unload', :to => lambda { |env| [200, {}, []] }
+ end
+ RUBY
+
+ require 'rack/test'
+ extend Rack::Test::Methods
+
+ require "#{rails_root}/config/environment"
+ setup_ar!
+
+ assert_equal [], ActiveRecord::Base.descendants
+ get "/load"
+ assert_equal [Post], ActiveRecord::Base.descendants
+ get "/unload"
+ assert_equal [], ActiveRecord::Base.descendants
+ end
+
+ protected
+
+ def setup_ar!
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
+ ActiveRecord::Migration.verbose = false
+ ActiveRecord::Schema.define(:version => 1) do
+ create_table :posts do |t|
+ t.string :title
+ end
+ end
+ end
+end
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index 999f666a64..e66e81ea2c 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -83,6 +83,17 @@ module ApplicationTests
assert_equal "Rack::Config", middleware.second
end
+ test "RAILS_CACHE does not respond to middleware" do
+ add_to_config "config.cache_store = :memory_store"
+ boot!
+ assert_equal "Rack::Runtime", middleware.third
+ end
+
+ test "RAILS_CACHE does respond to middleware" do
+ boot!
+ assert_equal "Rack::Runtime", middleware.fourth
+ end
+
test "insert middleware before" do
add_to_config "config.middleware.insert_before ActionDispatch::Static, Rack::Config"
boot!
diff --git a/railties/test/application/model_initialization_test.rb b/railties/test/application/model_initialization_test.rb
deleted file mode 100644
index 6a22f8d8df..0000000000
--- a/railties/test/application/model_initialization_test.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-require 'isolation/abstract_unit'
-
-class PostTest < Test::Unit::TestCase
- include ActiveSupport::Testing::Isolation
-
- def setup
- build_app
- boot_rails
- end
-
- def test_reload_should_reload_constants
- app_file "app/models/post.rb", <<-MODEL
- class Post < ActiveRecord::Base
- validates_acceptance_of :title, :accept => "omg"
- end
- MODEL
-
- require "#{rails_root}/config/environment"
- ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
- ActiveRecord::Migration.verbose = false
- ActiveRecord::Schema.define(:version => 1) do
- create_table :posts do |t|
- t.string :title
- end
- end
-
- p = Post.create(:title => 'omg')
- assert_equal 1, Post.count
- assert_equal 'omg', p.title
- p = Post.first
- assert_equal 'omg', p.title
- end
-end
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index 6b7a471494..40fb446b16 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -9,7 +9,7 @@ module ApplicationTests
boot_rails
FileUtils.rm_rf("#{app_path}/config/environments")
end
-
+
def test_gems_tasks_are_loaded_first_than_application_ones
app_file "lib/tasks/app.rake", <<-RUBY
$task_loaded = Rake::Task.task_defined?("db:create:all")
diff --git a/railties/test/application/runner_test.rb b/railties/test/application/runner_test.rb
new file mode 100644
index 0000000000..d37b7649e2
--- /dev/null
+++ b/railties/test/application/runner_test.rb
@@ -0,0 +1,49 @@
+require 'isolation/abstract_unit'
+
+module ApplicationTests
+ class RunnerTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ build_app
+ boot_rails
+
+ # Lets create a model so we have something to play with
+ app_file "app/models/user.rb", <<-MODEL
+ class User
+ def self.count
+ 42
+ end
+ end
+ MODEL
+ end
+
+ def test_should_run_ruby_statement
+ assert_match "42", Dir.chdir(app_path) { `bundle exec rails runner "puts User.count"` }
+ end
+
+ def test_should_run_file
+ app_file "script/count_users.rb", <<-SCRIPT
+ puts User.count
+ SCRIPT
+
+ assert_match "42", Dir.chdir(app_path) { `bundle exec rails runner "script/count_users.rb"` }
+ end
+
+ def test_should_set_dollar_0_to_file
+ app_file "script/dollar0.rb", <<-SCRIPT
+ puts $0
+ SCRIPT
+
+ assert_match "script/dollar0.rb", Dir.chdir(app_path) { `bundle exec rails runner "script/dollar0.rb"` }
+ end
+
+ def test_should_set_dollar_program_name_to_file
+ app_file "script/program_name.rb", <<-SCRIPT
+ puts $PROGRAM_NAME
+ SCRIPT
+
+ assert_match "script/program_name.rb", Dir.chdir(app_path) { `bundle exec rails runner "script/program_name.rb"` }
+ end
+ end
+end
diff --git a/railties/test/application/url_generation_test.rb b/railties/test/application/url_generation_test.rb
index 72cae23985..2b6ec26cd0 100644
--- a/railties/test/application/url_generation_test.rb
+++ b/railties/test/application/url_generation_test.rb
@@ -16,6 +16,7 @@ module ApplicationTests
class MyApp < Rails::Application
config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
config.session_store :cookie_store, :key => "_myapp_session"
+ config.active_support.deprecation = :log
end
MyApp.initialize!
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
index 65fbf61902..0472ca73a8 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -130,9 +130,9 @@ class ActionsTest < Rails::Generators::TestCase
def test_environment_should_include_data_in_environment_initializer_block
run_generator
- load_paths = 'config.load_paths += %w["#{Rails.root}/app/extras"]'
- action :environment, load_paths
- assert_file 'config/application.rb', /#{Regexp.escape(load_paths)}/
+ autoload_paths = 'config.autoload_paths += %w["#{Rails.root}/app/extras"]'
+ action :environment, autoload_paths
+ assert_file 'config/application.rb', /#{Regexp.escape(autoload_paths)}/
end
def test_environment_with_block_should_include_block_contents_in_environment_initializer_block
diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb
index 6ea722e239..f9d1e42d24 100644
--- a/railties/test/generators/migration_generator_test.rb
+++ b/railties/test/generators/migration_generator_test.rb
@@ -62,4 +62,19 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
end
end
end
+
+ def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove
+ migration = "create_books"
+ run_generator [migration, "title:string", "content:text"]
+
+ assert_migration "db/migrate/#{migration}.rb" do |content|
+ assert_class_method :up, content do |up|
+ assert_match /^\s*$/, up
+ end
+
+ assert_class_method :down, content do |down|
+ assert_match /^\s*$/, down
+ end
+ end
+ end
end
diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb
index e73dd237fb..1badae0713 100644
--- a/railties/test/generators/named_base_test.rb
+++ b/railties/test/generators/named_base_test.rb
@@ -93,6 +93,16 @@ class NamedBaseTest < Rails::Generators::TestCase
assert_name g, "application", :application_name
end
+ def test_index_helper
+ g = generator ['Post']
+ assert_name g, 'posts', :index_helper
+ end
+
+ def test_index_helper_with_uncountable
+ g = generator ['Sheep']
+ assert_name g, 'sheep_index', :index_helper
+ end
+
protected
def assert_name(generator, value, method)
diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb
index 96fd7a0a72..55d5bd6f83 100644
--- a/railties/test/generators/resource_generator_test.rb
+++ b/railties/test/generators/resource_generator_test.rb
@@ -59,14 +59,6 @@ class ResourceGeneratorTest < Rails::Generators::TestCase
end
end
- def test_singleton_resource
- run_generator ["account", "--singleton"]
-
- assert_file "config/routes.rb" do |route|
- assert_match /resource :account$/, route
- end
- end
-
def test_plural_names_are_singularized
content = run_generator ["accounts".freeze]
assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index 8040b22fe6..d55ed22975 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -78,20 +78,6 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
end
end
- def test_generates_singleton_controller
- run_generator ["User", "name:string", "age:integer", "--singleton"]
-
- assert_file "app/controllers/users_controller.rb" do |content|
- assert_no_match /def index/, content
- end
-
- assert_file "test/functional/users_controller_test.rb" do |content|
- assert_no_match /test "should get index"/, content
- end
-
- assert_no_file "app/views/users/index.html.erb"
- end
-
def test_skip_helper_if_required
run_generator ["User", "name:string", "age:integer", "--no-helper"]
assert_no_file "app/helpers/users_helper.rb"
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index e8e622fe5c..ea469cb3c8 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -110,4 +110,110 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Stylesheets (should not be removed)
assert_file "public/stylesheets/scaffold.css"
end
+
+ def test_scaffold_with_namespace_on_invoke
+ run_generator [ "admin/role", "name:string", "description:string" ]
+
+ # Model
+ assert_file "app/models/admin.rb", /module Admin/
+ assert_file "app/models/admin/role.rb", /class Admin::Role < ActiveRecord::Base/
+ assert_file "test/unit/admin/role_test.rb", /class Admin::RoleTest < ActiveSupport::TestCase/
+ assert_file "test/fixtures/admin/roles.yml"
+ assert_migration "db/migrate/create_admin_roles.rb"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_match /namespace :admin do resources :roles end$/, route
+ end
+
+ # Controller
+ assert_file "app/controllers/admin/roles_controller.rb" do |content|
+ assert_match /class Admin::RolesController < ApplicationController/, content
+
+ assert_instance_method :index, content do |m|
+ assert_match /@admin_roles = Admin::Role\.all/, m
+ end
+
+ assert_instance_method :show, content do |m|
+ assert_match /@admin_role = Admin::Role\.find\(params\[:id\]\)/, m
+ end
+
+ assert_instance_method :new, content do |m|
+ assert_match /@admin_role = Admin::Role\.new/, m
+ end
+
+ assert_instance_method :edit, content do |m|
+ assert_match /@admin_role = Admin::Role\.find\(params\[:id\]\)/, m
+ end
+
+ assert_instance_method :create, content do |m|
+ assert_match /@admin_role = Admin::Role\.new\(params\[:admin_role\]\)/, m
+ assert_match /@admin_role\.save/, m
+ assert_match /@admin_role\.errors/, m
+ end
+
+ assert_instance_method :update, content do |m|
+ assert_match /@admin_role = Admin::Role\.find\(params\[:id\]\)/, m
+ assert_match /@admin_role\.update_attributes\(params\[:admin_role\]\)/, m
+ assert_match /@admin_role\.errors/, m
+ end
+
+ assert_instance_method :destroy, content do |m|
+ assert_match /@admin_role = Admin::Role\.find\(params\[:id\]\)/, m
+ assert_match /@admin_role\.destroy/, m
+ end
+ end
+
+ assert_file "test/functional/admin/roles_controller_test.rb",
+ /class Admin::RolesControllerTest < ActionController::TestCase/
+
+ # Views
+ %w(
+ index
+ edit
+ new
+ show
+ _form
+ ).each { |view| assert_file "app/views/admin/roles/#{view}.html.erb" }
+ assert_no_file "app/views/layouts/admin/roles.html.erb"
+
+ # Helpers
+ assert_file "app/helpers/admin/roles_helper.rb"
+ assert_file "test/unit/helpers/admin/roles_helper_test.rb"
+
+ # Stylesheets
+ assert_file "public/stylesheets/scaffold.css"
+ end
+
+ def test_scaffold_with_namespace_on_revoke
+ run_generator [ "admin/role", "name:string", "description:string" ]
+ run_generator [ "admin/role" ], :behavior => :revoke
+
+ # Model
+ assert_file "app/models/admin.rb" # ( should not be remove )
+ assert_no_file "app/models/admin/role.rb"
+ assert_no_file "test/unit/admin/role_test.rb"
+ assert_no_file "test/fixtures/admin/roles.yml"
+ assert_no_migration "db/migrate/create_admin_roles.rb"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_no_match /namespace :admin do resources :roles end$/, route
+ end
+
+ # Controller
+ assert_no_file "app/controllers/admin/roles_controller.rb"
+ assert_no_file "test/functional/admin/roles_controller_test.rb"
+
+ # Views
+ assert_no_file "app/views/admin/roles"
+ assert_no_file "app/views/layouts/admin/roles.html.erb"
+
+ # Helpers
+ assert_no_file "app/helpers/admin/roles_helper.rb"
+ assert_no_file "test/unit/helpers/admin/roles_helper_test.rb"
+
+ # Stylesheets (should not be removed)
+ assert_file "public/stylesheets/scaffold.css"
+ end
end
diff --git a/railties/test/initializable_test.rb b/railties/test/initializable_test.rb
index 74301a5dc5..72c35879c5 100644
--- a/railties/test/initializable_test.rb
+++ b/railties/test/initializable_test.rb
@@ -5,10 +5,7 @@ module InitializableTests
class Foo
include Rails::Initializable
-
- class << self
- attr_accessor :foo, :bar
- end
+ attr_accessor :foo, :bar
initializer :start do
@foo ||= 0
@@ -158,30 +155,22 @@ module InitializableTests
include ActiveSupport::Testing::Isolation
test "initializers run" do
- Foo.run_initializers
- assert_equal 1, Foo.foo
+ foo = Foo.new
+ foo.run_initializers
+ assert_equal 1, foo.foo
end
test "initializers are inherited" do
- Bar.run_initializers
- assert_equal [1, 1], [Bar.foo, Bar.bar]
+ bar = Bar.new
+ bar.run_initializers
+ assert_equal [1, 1], [bar.foo, bar.bar]
end
test "initializers only get run once" do
- Foo.run_initializers
- Foo.run_initializers
- assert_equal 1, Foo.foo
- end
-
- test "running initializers on children does not effect the parent" do
- Bar.run_initializers
- assert_nil Foo.foo
- assert_nil Foo.bar
- end
-
- test "initializing with modules" do
- Word.run_initializers
- assert_equal "bird", $word
+ foo = Foo.new
+ foo.run_initializers
+ foo.run_initializers
+ assert_equal 1, foo.foo
end
test "creating initializer without a block raises an error" do
@@ -198,19 +187,19 @@ module InitializableTests
class BeforeAfter < ActiveSupport::TestCase
test "running on parent" do
$arr = []
- Parent.run_initializers
+ Parent.new.run_initializers
assert_equal [5, 1, 2], $arr
end
test "running on child" do
$arr = []
- Child.run_initializers
+ Child.new.run_initializers
assert_equal [5, 3, 1, 4, 2], $arr
end
test "handles dependencies introduced before all initializers are loaded" do
$arr = []
- Interdependent::Application.run_initializers
+ Interdependent::Application.new.run_initializers
assert_equal [1, 2, 3, 4], $arr
end
end
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index b46ac0efaf..390c0ab543 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -100,7 +100,7 @@ module TestHelpers
end
end
- add_to_config 'config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"; config.session_store :cookie_store, :key => "_myapp_session"'
+ add_to_config 'config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"; config.session_store :cookie_store, :key => "_myapp_session"; config.active_support.deprecation = :log'
end
def make_basic_app
@@ -110,6 +110,7 @@ module TestHelpers
app = Class.new(Rails::Application)
app.config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
app.config.session_store :cookie_store, :key => "_myapp_session"
+ app.config.active_support.deprecation = :log
yield app if block_given?
app.initialize!
diff --git a/railties/test/log_subscriber_test.rb b/railties/test/log_subscriber_test.rb
deleted file mode 100644
index a3a755ae62..0000000000
--- a/railties/test/log_subscriber_test.rb
+++ /dev/null
@@ -1,123 +0,0 @@
-require 'abstract_unit'
-require 'rails/log_subscriber/test_helper'
-
-class MyLogSubscriber < Rails::LogSubscriber
- attr_reader :event
-
- def some_event(event)
- @event = event
- info event.name
- end
-
- def foo(event)
- debug "debug"
- info "info"
- warn "warn"
- end
-
- def bar(event)
- info "#{color("cool", :red)}, #{color("isn't it?", :blue, true)}"
- end
-
- def puke(event)
- raise "puke"
- end
-end
-
-class SyncLogSubscriberTest < ActiveSupport::TestCase
- include Rails::LogSubscriber::TestHelper
-
- def setup
- super
- @log_subscriber = MyLogSubscriber.new
- end
-
- def teardown
- super
- Rails::LogSubscriber.log_subscribers.clear
- end
-
- def instrument(*args, &block)
- ActiveSupport::Notifications.instrument(*args, &block)
- end
-
- def test_proxies_method_to_rails_logger
- @log_subscriber.foo(nil)
- assert_equal %w(debug), @logger.logged(:debug)
- assert_equal %w(info), @logger.logged(:info)
- assert_equal %w(warn), @logger.logged(:warn)
- end
-
- def test_set_color_for_messages
- Rails::LogSubscriber.colorize_logging = true
- @log_subscriber.bar(nil)
- assert_equal "\e[31mcool\e[0m, \e[1m\e[34misn't it?\e[0m", @logger.logged(:info).last
- end
-
- def test_does_not_set_color_if_colorize_logging_is_set_to_false
- @log_subscriber.bar(nil)
- assert_equal "cool, isn't it?", @logger.logged(:info).last
- end
-
- def test_event_is_sent_to_the_registered_class
- Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber
- instrument "some_event.my_log_subscriber"
- wait
- assert_equal %w(some_event.my_log_subscriber), @logger.logged(:info)
- end
-
- def test_event_is_an_active_support_notifications_event
- Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber
- instrument "some_event.my_log_subscriber"
- wait
- assert_kind_of ActiveSupport::Notifications::Event, @log_subscriber.event
- end
-
- def test_does_not_send_the_event_if_it_doesnt_match_the_class
- Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber
- instrument "unknown_event.my_log_subscriber"
- wait
- # If we get here, it means that NoMethodError was not raised.
- end
-
- def test_does_not_send_the_event_if_logger_is_nil
- Rails.logger = nil
- @log_subscriber.expects(:some_event).never
- Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber
- instrument "some_event.my_log_subscriber"
- wait
- end
-
- def test_does_not_fail_with_non_namespaced_events
- Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber
- instrument "whatever"
- wait
- end
-
- def test_flushes_loggers
- Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber
- Rails::LogSubscriber.flush_all!
- assert_equal 1, @logger.flush_count
- end
-
- def test_flushes_the_same_logger_just_once
- Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber
- Rails::LogSubscriber.add :another, @log_subscriber
- Rails::LogSubscriber.flush_all!
- wait
- assert_equal 1, @logger.flush_count
- end
-
- def test_logging_does_not_die_on_failures
- Rails::LogSubscriber.add :my_log_subscriber, @log_subscriber
- instrument "puke.my_log_subscriber"
- instrument "some_event.my_log_subscriber"
- wait
-
- assert_equal 1, @logger.logged(:info).size
- assert_equal 'some_event.my_log_subscriber', @logger.logged(:info).last
-
- assert_equal 1, @logger.logged(:error).size
- assert_equal 'Could not log "puke.my_log_subscriber" event. RuntimeError: puke', @logger.logged(:error).last
- end
-end \ No newline at end of file
diff --git a/railties/test/paths_test.rb b/railties/test/paths_test.rb
index 92c7b2ba0e..008247cb1a 100644
--- a/railties/test/paths_test.rb
+++ b/railties/test/paths_test.rb
@@ -120,36 +120,36 @@ class PathsTest < ActiveSupport::TestCase
test "it is possible to add a path that should be loaded only once" do
@root.app = "/app"
- @root.app.load_once!
- assert @root.app.load_once?
- assert @root.load_once.include?(@root.app.paths.first)
+ @root.app.autoload_once!
+ assert @root.app.autoload_once?
+ assert @root.autoload_once.include?(@root.app.paths.first)
end
test "it is possible to add a path without assignment and specify it should be loaded only once" do
- @root.app "/app", :load_once => true
- assert @root.app.load_once?
- assert @root.load_once.include?("/app")
+ @root.app "/app", :autoload_once => true
+ assert @root.app.autoload_once?
+ assert @root.autoload_once.include?("/app")
end
test "it is possible to add multiple paths without assignment and specify it should be loaded only once" do
- @root.app "/app", "/app2", :load_once => true
- assert @root.app.load_once?
- assert @root.load_once.include?("/app")
- assert @root.load_once.include?("/app2")
+ @root.app "/app", "/app2", :autoload_once => true
+ assert @root.app.autoload_once?
+ assert @root.autoload_once.include?("/app")
+ assert @root.autoload_once.include?("/app2")
end
- test "making a path load_once more than once only includes it once in @root.load_once" do
+ test "making a path autoload_once more than once only includes it once in @root.load_once" do
@root.app = "/app"
- @root.app.load_once!
- @root.app.load_once!
- assert_equal 1, @root.load_once.select {|p| p == @root.app.paths.first }.size
+ @root.app.autoload_once!
+ @root.app.autoload_once!
+ assert_equal 1, @root.autoload_once.select {|p| p == @root.app.paths.first }.size
end
- test "paths added to a load_once path should be added to the load_once collection" do
+ test "paths added to a load_once path should be added to the autoload_once collection" do
@root.app = "/app"
- @root.app.load_once!
+ @root.app.autoload_once!
@root.app << "/app2"
- assert_equal 2, @root.load_once.size
+ assert_equal 2, @root.autoload_once.size
end
test "it is possible to mark a path as eager" do
@@ -173,11 +173,11 @@ class PathsTest < ActiveSupport::TestCase
end
test "it is possible to create a path without assignment and mark it both as eager and load once" do
- @root.app "/app", :eager_load => true, :load_once => true
+ @root.app "/app", :eager_load => true, :autoload_once => true
assert @root.app.eager_load?
- assert @root.app.load_once?
+ assert @root.app.autoload_once?
assert @root.eager_load.include?("/app")
- assert @root.load_once.include?("/app")
+ assert @root.autoload_once.include?("/app")
end
test "making a path eager more than once only includes it once in @root.eager_paths" do
@@ -218,16 +218,16 @@ class PathsTest < ActiveSupport::TestCase
assert_equal ["/app"], @root.load_paths
end
- test "adding a path to the eager paths also adds it to the load path" do
+ test "a path can be marked as autoload path" do
@root.app = "app"
- @root.app.eager_load!
- assert_equal ["/foo/bar/app"], @root.load_paths
+ @root.app.autoload!
+ @root.app.models = "app/models"
+ assert_equal ["/foo/bar/app"], @root.autoload_paths
end
- test "adding a path to the load once paths also adds it to the load path" do
- @root.app = "app"
- @root.app.load_once!
- assert_equal ["/foo/bar/app"], @root.load_paths
+ test "a path can be marked as autoload on creation" do
+ @root.app "/app", :autoload => true
+ assert @root.app.autoload?
+ assert_equal ["/app"], @root.autoload_paths
end
-
end
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index b3f65fd00d..7410a10712 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -20,10 +20,6 @@ module RailtiesTest
end
end
- def reload_config
- :reload_engines
- end
-
test "Rails::Engine itself does not respond to config" do
boot_rails
assert !Rails::Engine.respond_to?(:config)
@@ -41,7 +37,7 @@ module RailtiesTest
boot_rails
- initializers = Rails.application.initializers
+ initializers = Rails.application.initializers.tsort
index = initializers.index { |i| i.name == "dummy_initializer" }
selection = initializers[(index-3)..(index)].map(&:name).map(&:to_s)
diff --git a/railties/test/railties/i18n_railtie_test.rb b/railties/test/railties/i18n_railtie_test.rb
deleted file mode 100644
index 2b1950b3d5..0000000000
--- a/railties/test/railties/i18n_railtie_test.rb
+++ /dev/null
@@ -1,89 +0,0 @@
-require "isolation/abstract_unit"
-
-module RailtiesTest
- class I18nRailtieTest < Test::Unit::TestCase
- include ActiveSupport::Testing::Isolation
-
- def setup
- build_app
- boot_rails
- FileUtils.rm_rf("#{app_path}/config/environments")
- require "rails/all"
- end
-
- def load_app
- require "#{app_path}/config/environment"
- end
-
- def assert_fallbacks(fallbacks)
- fallbacks.each do |locale, expected|
- actual = I18n.fallbacks[locale]
- assert_equal expected, actual, "expected fallbacks for #{locale.inspect} to be #{expected.inspect}, but were #{actual.inspect}"
- end
- end
-
- def assert_no_fallbacks
- assert !I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
- end
-
- test "config.i18n.load_path gets added to I18n.load_path" do
- I18n.load_path = ['existing/path/to/locales']
- I18n::Railtie.config.i18n.load_path = ['new/path/to/locales']
- load_app
-
- assert I18n.load_path.include?('existing/path/to/locales')
- assert I18n.load_path.include?('new/path/to/locales')
- end
-
- test "not using config.i18n.fallbacks does not initialize I18n.fallbacks" do
- I18n.backend = Class.new { include I18n::Backend::Base }.new
- load_app
- assert_no_fallbacks
- end
-
- test "config.i18n.fallbacks = true initializes I18n.fallbacks with default settings" do
- I18n::Railtie.config.i18n.fallbacks = true
- load_app
- assert I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
- assert_fallbacks :de => [:de, :en]
- end
-
- test "config.i18n.fallbacks = true initializes I18n.fallbacks with default settings even when backend changes" do
- I18n::Railtie.config.i18n.fallbacks = true
- I18n::Railtie.config.i18n.backend = Class.new { include I18n::Backend::Base }.new
- load_app
- assert I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
- assert_fallbacks :de => [:de, :en]
- end
-
- test "config.i18n.fallbacks.defaults = [:'en-US'] initializes fallbacks with en-US as a fallback default" do
- I18n::Railtie.config.i18n.fallbacks.defaults = [:'en-US']
- load_app
- assert_fallbacks :de => [:de, :'en-US', :en]
- end
-
- test "config.i18n.fallbacks.map = { :ca => :'es-ES' } initializes fallbacks with a mapping ca => es-ES" do
- I18n::Railtie.config.i18n.fallbacks.map = { :ca => :'es-ES' }
- load_app
- assert_fallbacks :ca => [:ca, :"es-ES", :es, :en]
- end
-
- test "[shortcut] config.i18n.fallbacks = [:'en-US'] initializes fallbacks with en-US as a fallback default" do
- I18n::Railtie.config.i18n.fallbacks = [:'en-US']
- load_app
- assert_fallbacks :de => [:de, :'en-US', :en]
- end
-
- test "[shortcut] config.i18n.fallbacks = [{ :ca => :'es-ES' }] initializes fallbacks with a mapping de-AT => de-DE" do
- I18n::Railtie.config.i18n.fallbacks.map = { :ca => :'es-ES' }
- load_app
- assert_fallbacks :ca => [:ca, :"es-ES", :es, :en]
- end
-
- test "[shortcut] config.i18n.fallbacks = [:'en-US', { :ca => :'es-ES' }] initializes fallbacks with the given arguments" do
- I18n::Railtie.config.i18n.fallbacks = [:'en-US', { :ca => :'es-ES' }]
- load_app
- assert_fallbacks :ca => [:ca, :"es-ES", :es, :'en-US', :en]
- end
- end
-end \ No newline at end of file
diff --git a/railties/test/railties/plugin_test.rb b/railties/test/railties/plugin_test.rb
index 0f5f29468c..b143f56484 100644
--- a/railties/test/railties/plugin_test.rb
+++ b/railties/test/railties/plugin_test.rb
@@ -15,10 +15,6 @@ module RailtiesTest
end
end
- def reload_config
- :reload_plugins
- end
-
test "Rails::Plugin itself does not respond to config" do
boot_rails
assert !Rails::Plugin.respond_to?(:config)
@@ -37,6 +33,32 @@ module RailtiesTest
assert_equal "Bukkits", Bukkits.name
end
+ test "plugin gets added to dependency list" do
+ boot_rails
+ assert_equal "Another", Another.name
+ end
+
+ test "plugin constants get reloaded if config.reload_plugins is set to true" do
+ add_to_config <<-RUBY
+ config.reload_plugins = true
+ RUBY
+
+ boot_rails
+
+ assert_equal "Another", Another.name
+ ActiveSupport::Dependencies.clear
+ @plugin.delete("lib/another.rb")
+ assert_raises(NameError) { Another }
+ end
+
+ test "plugin constants are not reloaded by default" do
+ boot_rails
+ assert_equal "Another", Another.name
+ ActiveSupport::Dependencies.clear
+ @plugin.delete("lib/another.rb")
+ assert_nothing_raised { Another }
+ end
+
test "it loads the plugin's init.rb file" do
boot_rails
assert_equal "loaded", BUKKITS
diff --git a/railties/test/railties/railtie_test.rb b/railties/test/railties/railtie_test.rb
index 2accaca855..c74cc01dc1 100644
--- a/railties/test/railties/railtie_test.rb
+++ b/railties/test/railties/railtie_test.rb
@@ -48,15 +48,6 @@ module RailtiesTest
assert_equal "hello", AppTemplate::Application.config.foo.greetings
end
- test "railtie can add log subscribers" do
- begin
- class Foo < Rails::Railtie ; log_subscriber(:foo, Rails::LogSubscriber.new) ; end
- assert_kind_of Rails::LogSubscriber, Rails::LogSubscriber.log_subscribers[0]
- ensure
- Rails::LogSubscriber.log_subscribers.clear
- end
- end
-
test "railtie can add to_prepare callbacks" do
$to_prepare = false
class Foo < Rails::Railtie ; config.to_prepare { $to_prepare = true } ; end
diff --git a/railties/test/railties/shared_tests.rb b/railties/test/railties/shared_tests.rb
index 3f78d7d3fe..ce7c55c11c 100644
--- a/railties/test/railties/shared_tests.rb
+++ b/railties/test/railties/shared_tests.rb
@@ -10,51 +10,25 @@ module RailtiesTest
@app ||= Rails.application
end
- def test_plugin_puts_its_lib_directory_on_load_path
+ def test_puts_its_lib_directory_on_load_path
boot_rails
require "another"
assert_equal "Another", Another.name
end
- def test_plugin_paths_get_added_to_as_dependency_list
- boot_rails
- assert_equal "Another", Another.name
- end
-
- def test_plugins_constants_are_not_reloaded_by_default
- boot_rails
- assert_equal "Another", Another.name
- ActiveSupport::Dependencies.clear
- @plugin.delete("lib/another.rb")
- assert_nothing_raised { Another }
- end
-
- def test_plugin_constants_get_reloaded_if_config_reload_plugins
- add_to_config <<-RUBY
- config.#{reload_config} = true
- RUBY
-
- boot_rails
-
- assert_equal "Another", Another.name
- ActiveSupport::Dependencies.clear
- @plugin.delete("lib/another.rb")
- assert_raises(NameError) { Another }
- end
-
- def test_plugin_puts_its_models_directory_on_load_path
+ def test_puts_its_models_directory_on_autoload_path
@plugin.write "app/models/my_bukkit.rb", "class MyBukkit ; end"
boot_rails
assert_nothing_raised { MyBukkit }
end
- def test_plugin_puts_its_controllers_directory_on_the_load_path
+ def test_puts_its_controllers_directory_on_autoload_path
@plugin.write "app/controllers/bukkit_controller.rb", "class BukkitController ; end"
boot_rails
assert_nothing_raised { BukkitController }
end
- def test_plugin_adds_its_views_to_view_paths
+ def test_adds_its_views_to_view_paths
@plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY
class BukkitController < ActionController::Base
def index
@@ -72,7 +46,7 @@ module RailtiesTest
assert_equal "Hello bukkits\n", response[2].body
end
- def test_plugin_adds_its_views_to_view_paths_with_lower_proriority
+ def test_adds_its_views_to_view_paths_with_lower_proriority_than_app_ones
@plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY
class BukkitController < ActionController::Base
def index
@@ -91,7 +65,7 @@ module RailtiesTest
assert_equal "Hi bukkits\n", response[2].body
end
- def test_plugin_adds_helpers_to_controller_views
+ def test_adds_helpers_to_controller_views
@plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY
class BukkitController < ActionController::Base
def index
@@ -116,11 +90,10 @@ module RailtiesTest
assert_equal "Hello bukkits\n", response[2].body
end
- def test_plugin_eager_load_any_path_under_app
+ def test_autoload_any_path_under_app
@plugin.write "app/anything/foo.rb", <<-RUBY
module Foo; end
RUBY
-
boot_rails
assert Foo
end
@@ -269,7 +242,7 @@ YAML
assert_equal "Rendered from namespace", last_response.body
end
- def test_plugin_initializers
+ def test_initializers
$plugin_initializer = false
@plugin.write "config/initializers/foo.rb", <<-RUBY
$plugin_initializer = true
@@ -279,7 +252,7 @@ YAML
assert $plugin_initializer
end
- def test_plugin_midleware_referenced_in_configuration
+ def test_midleware_referenced_in_configuration
@plugin.write "lib/bukkits.rb", <<-RUBY
class Bukkits
def initialize(app)