aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG19
-rwxr-xr-xrailties/bin/rails2
-rw-r--r--railties/guides/source/action_controller_overview.textile2
-rw-r--r--railties/guides/source/action_mailer_basics.textile25
-rw-r--r--railties/guides/source/action_view_overview.textile6
-rw-r--r--railties/guides/source/active_record_querying.textile83
-rw-r--r--railties/guides/source/active_record_validations_callbacks.textile10
-rw-r--r--railties/guides/source/active_support_core_extensions.textile102
-rw-r--r--railties/guides/source/asset_pipeline.textile320
-rw-r--r--railties/guides/source/association_basics.textile4
-rw-r--r--railties/guides/source/caching_with_rails.textile1
-rw-r--r--railties/guides/source/command_line.textile192
-rw-r--r--railties/guides/source/configuring.textile45
-rw-r--r--railties/guides/source/contributing_to_ruby_on_rails.textile4
-rw-r--r--railties/guides/source/debugging_rails_applications.textile26
-rw-r--r--railties/guides/source/form_helpers.textile4
-rw-r--r--railties/guides/source/getting_started.textile55
-rw-r--r--railties/guides/source/initialization.textile4
-rw-r--r--railties/guides/source/migrations.textile2
-rw-r--r--railties/guides/source/nested_model_forms.textile12
-rw-r--r--railties/guides/source/performance_testing.textile10
-rw-r--r--railties/guides/source/plugins.textile2
-rw-r--r--railties/guides/source/rails_application_templates.textile10
-rw-r--r--railties/guides/source/security.textile10
-rw-r--r--railties/guides/source/testing.textile2
-rw-r--r--railties/lib/rails.rb26
-rw-r--r--railties/lib/rails/all.rb1
-rw-r--r--railties/lib/rails/application.rb15
-rw-r--r--railties/lib/rails/application/configuration.rb2
-rw-r--r--railties/lib/rails/application/railties.rb2
-rw-r--r--railties/lib/rails/commands/plugin.rb4
-rw-r--r--railties/lib/rails/commands/runner.rb4
-rw-r--r--railties/lib/rails/engine.rb26
-rw-r--r--railties/lib/rails/generators.rb5
-rw-r--r--railties/lib/rails/generators/actions.rb8
-rw-r--r--railties/lib/rails/generators/app_base.rb61
-rw-r--r--railties/lib/rails/generators/base.rb6
-rw-r--r--railties/lib/rails/generators/generated_attribute.rb2
-rw-r--r--railties/lib/rails/generators/js/assets/assets_generator.rb13
-rw-r--r--railties/lib/rails/generators/js/assets/templates/javascript.js2
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile14
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb10
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml62
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml17
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt5
-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/routes.rb2
-rw-r--r--railties/lib/rails/generators/rails/assets/assets_generator.rb11
-rw-r--r--railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee3
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb14
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/Gemfile7
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt14
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb8
-rw-r--r--railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb2
-rw-r--r--railties/lib/rails/info.rb4
-rw-r--r--railties/lib/rails/railtie.rb8
-rw-r--r--railties/lib/rails/source_annotation_extractor.rb8
-rw-r--r--railties/lib/rails/tasks.rb1
-rw-r--r--railties/lib/rails/tasks/assets.rake21
-rw-r--r--railties/lib/rails/tasks/engine.rake2
-rw-r--r--railties/lib/rails/test_unit/testing.rake8
-rw-r--r--railties/lib/rails/version.rb4
-rw-r--r--railties/railties.gemspec4
-rw-r--r--railties/test/application/assets_test.rb42
-rw-r--r--railties/test/application/configuration_test.rb24
-rw-r--r--railties/test/application/initializers/i18n_test.rb6
-rw-r--r--railties/test/application/rake_test.rb37
-rw-r--r--railties/test/application/runner_test.rb4
-rw-r--r--railties/test/fixtures/lib/generators/wrong_generator.rb3
-rw-r--r--railties/test/generators/app_generator_test.rb50
-rw-r--r--railties/test/generators/assets_generator_test.rb10
-rw-r--r--railties/test/generators/controller_generator_test.rb2
-rw-r--r--railties/test/generators/generated_attribute_test.rb13
-rw-r--r--railties/test/generators/model_generator_test.rb12
-rw-r--r--railties/test/generators/plugin_new_generator_test.rb38
-rw-r--r--railties/test/generators/scaffold_generator_test.rb33
-rw-r--r--railties/test/generators_test.rb6
-rw-r--r--railties/test/isolation/abstract_unit.rb4
-rw-r--r--railties/test/railties/generators_test.rb5
-rw-r--r--railties/test/railties/shared_tests.rb24
84 files changed, 1206 insertions, 483 deletions
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index 880849d2ec..a9b4deb551 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -1,27 +1,26 @@
*Rails 3.2.0 (unreleased)*
+* Attributes on scaffold and model generators default to string. This allows the following: "rails g scaffold Post title body:text author" [José Valim]
+
* Removed old plugin generator (`rails generate plugin`) in favor of `rails plugin new` command. [Guillermo Iguaran]
* Removed old 'config.paths.app.controller' API in favor of 'config.paths["app/controller"]' API. [Guillermo Iguaran]
-
*Rails 3.1.0 (unreleased)*
-* The new rake task assets:clean removes precompiled assets. [fxn]
+* Make sprockets/railtie require explicit and add --skip-sprockets to app generator [José Valim]
-* Application and plugin generation run bundle install unless --skip-gemfile or --skip-bundle. [fxn]
+* Added Rails.groups that automatically handles Rails.env and ENV["RAILS_GROUPS"] [José Valim]
-* Fixed database tasks for jdbc* adapters #jruby
-
- [Rashmi Yadav]
+* The new rake task assets:clean removes precompiled assets. [fxn]
-* Template generation for jdbcpostgresql #jruby
+* Application and plugin generation run bundle install unless --skip-gemfile or --skip-bundle. [fxn]
- [Vishnu Atrai]
+* Fixed database tasks for jdbc* adapters #jruby [Rashmi Yadav]
-* Template generation for jdbcmysql and jdbcsqlite3 #jruby
+* Template generation for jdbcpostgresql #jruby [Vishnu Atrai]
- [Arun Agrawal]
+* Template generation for jdbcmysql and jdbcsqlite3 #jruby [Arun Agrawal]
* The -j option of the application generator accepts an arbitrary string. If passed "foo",
the gem "foo-rails" is added to the Gemfile, and the application JavaScript manifest
diff --git a/railties/bin/rails b/railties/bin/rails
new file mode 100755
index 0000000000..a7d6938e0d
--- /dev/null
+++ b/railties/bin/rails
@@ -0,0 +1,2 @@
+#!/usr/bin/env ruby
+require "rails/cli" \ No newline at end of file
diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile
index 891bae3d5e..073e3bddcf 100644
--- a/railties/guides/source/action_controller_overview.textile
+++ b/railties/guides/source/action_controller_overview.textile
@@ -802,7 +802,7 @@ class DinnerController
end
</ruby>
-Just like the filter, you could also passing +:only+ and +:except+ to enforce the secure connection only to specific actions
+Just like the filter, you could also passing +:only+ and +:except+ to enforce the secure connection only to specific actions.
<ruby>
class DinnerController
diff --git a/railties/guides/source/action_mailer_basics.textile b/railties/guides/source/action_mailer_basics.textile
index e1ff49cd60..2eaee158ff 100644
--- a/railties/guides/source/action_mailer_basics.textile
+++ b/railties/guides/source/action_mailer_basics.textile
@@ -284,16 +284,37 @@ class UserMailer < ActionMailer::Base
@user = user
@url = "http://example.com/login"
mail(:to => user.email,
+ :subject => "Welcome to My Awesome Site",
+ :template_path => 'notifications',
+ :template_name => 'another')
+ end
+ end
+
+end
+</ruby>
+
+In this case it will look for templates at +app/views/notifications+ with name +another+.
+
+If you want more flexibility you can also pass a block and render specific templates or even render inline or text without using a template file:
+
+<ruby>
+class UserMailer < ActionMailer::Base
+ default :from => "notifications@example.com"
+
+ def welcome_email(user)
+ @user = user
+ @url = "http://example.com/login"
+ mail(:to => user.email,
:subject => "Welcome to My Awesome Site") do |format|
format.html { render 'another_template' }
- format.text { render 'another_template' }
+ format.text { render :text => 'Render text' }
end
end
end
</ruby>
-Will render 'another_template.text.erb' and 'another_template.html.erb'. The render command is the same one used inside of Action Controller, so you can use all the same options, such as <tt>:text</tt> etc.
+This will render the template 'another_template.html.erb' for the HTML part and use the rendered text for the text part. The render command is the same one used inside of Action Controller, so you can use all the same options, such as <tt>:text</tt>, <tt>:inline</tt> etc.
h4. Action Mailer Layouts
diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile
index a3454579ad..7703d6c720 100644
--- a/railties/guides/source/action_view_overview.textile
+++ b/railties/guides/source/action_view_overview.textile
@@ -165,7 +165,7 @@ will produce
<em>emphasized</em>
<em><b>emph &amp; bold</b></em>
<a href="http://rubyonrails.org">A link</a>
-<target option="fast" name="compile" \>
+<target option="fast" name="compile" />
</html>
Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
@@ -211,7 +211,7 @@ xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
end
</ruby>
-h5. Template caching
+h5. Template Caching
By default, Rails will compile each template to a method in order to render it. When you alter a template, Rails will check the file's modification time and recompile it in development mode.
@@ -235,7 +235,7 @@ This will render a file named +_menu.html.erb+ at that point within the view is
That code will pull in the partial from +app/views/shared/_menu.html.erb+.
-h5. Using Partials to Simplify Views
+h5. Using Partials to simplify Views
One way to use partials is to treat them as the equivalent of subroutines: as a way to move details out of a view so that you can grasp what's going on more easily. For example, you might have a view that looked like this:
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile
index b4ce60fcaa..082f9eda7d 100644
--- a/railties/guides/source/active_record_querying.textile
+++ b/railties/guides/source/active_record_querying.textile
@@ -57,6 +57,7 @@ The methods are:
* +group+
* +order+
* +reorder+
+* +reverse_order+
* +limit+
* +offset+
* +joins+
@@ -255,7 +256,7 @@ The above will yield the supplied block with +1000+ invoices every time.
h3. Conditions
-The +find+ method allows you to specify conditions to limit the records returned, representing the +WHERE+-part of the SQL statement. Conditions can either be specified as a string, array, or hash.
+The +where+ method allows you to specify conditions to limit the records returned, representing the +WHERE+-part of the SQL statement. Conditions can either be specified as a string, array, or hash.
h4. Pure String Conditions
@@ -465,7 +466,7 @@ To apply a +GROUP BY+ clause to the SQL fired by the finder, you can specify the
For example, if you want to find a collection of the dates orders were created on:
<ruby>
-Order.group("date(created_at)").order("created_at")
+Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)")
</ruby>
And this will give you a single +Order+ object for each date where there are orders in the database.
@@ -473,7 +474,7 @@ And this will give you a single +Order+ object for each date where there are ord
The SQL that would be executed would be something like this:
<sql>
-SELECT * FROM orders GROUP BY date(created_at) ORDER BY created_at
+SELECT date(created_at) as ordered_date, sum(price) as total_price FROM orders GROUP BY date(created_at)
</sql>
h3. Having
@@ -483,16 +484,16 @@ SQL uses the +HAVING+ clause to specify conditions on the +GROUP BY+ fields. You
For example:
<ruby>
-Order.group("date(created_at)").having("created_at < ?", 1.month.ago)
+Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)").having("sum(price) > ?", 100)
</ruby>
The SQL that would be executed would be something like this:
<sql>
-SELECT * FROM orders GROUP BY date(created_at) HAVING created_at < '2011-04-27'
+SELECT date(created_at) as ordered_date, sum(price) as total_price FROM orders GROUP BY date(created_at) HAVING sum(price) > 100
</sql>
-This will return single order objects for each day, but only those that are at least one month old.
+This will return single order objects for each day, but only those that are ordered more than $100 in a day.
h3. Overriding Conditions
@@ -550,6 +551,32 @@ In case the +reorder+ clause is not used, the SQL executed would be:
SELECT * FROM posts WHERE id = 10 ORDER BY posted_at DESC
</sql>
+h4. +reverse_order+
+
+The +reverse_order+ method reverses the ordering clause if specified.
+
+<ruby>
+Client.where("orders_count > 10").order(:name).reverse_order
+</ruby>
+
+The SQL that would be executed:
+<sql>
+SELECT * FROM clients WHERE orders_count > 10 ORDER BY name DESC
+</sql>
+
+If no ordering clause is specified in the query, the +reverse_order+ orders by the primary key in reverse order.
+
+<ruby>
+Client.where("orders_count > 10").reverse_order
+</ruby>
+
+The SQL that would be executed:
+<sql>
+SELECT * FROM clients WHERE orders_count > 10 ORDER BY clients.id DESC
+</sql>
+
+This method accepts *no* arguments.
+
h3. Readonly Objects
Active Record provides +readonly+ method on a relation to explicitly disallow modification or deletion of any of the returned object. Any attempt to alter or destroy a readonly record will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception.
@@ -938,6 +965,47 @@ Using a class method is the preferred way to accept arguments for scopes. These
category.posts.1_week_before(time)
</ruby>
+h4. Working with scopes
+
+Where a relational object is required, the +scoped+ method may come in handy. This will return an +ActiveRecord::Relation+ object which can have further scoping applied to it afterwards. A place where this may come in handy is on associations
+
+<ruby>
+client = Client.find_by_first_name("Ryan")
+orders = client.orders.scoped
+</ruby>
+
+With this new +orders+ object, we are able to ascertain that this object can have more scopes applied to it. For instance, if we wanted to return orders only in the last 30 days at a later point.
+
+<ruby>
+orders.where("created_at > ?", 30.days.ago)
+</ruby>
+
+h4. Applying a default scope
+
+If we wish for a scope to be applied across all queries to the model we can use the +default_scope+ method within the model itself.
+
+<ruby>
+class Client < ActiveRecord::Base
+ default_scope where("removed_at IS NULL")
+end
+</ruby>
+
+When queries are executed on this model, the SQL query will now look something like this:
+
+<sql>
+SELECT * FROM clients WHERE removed_at IS NULL
+</sql>
+
+h4. Removing all scoping
+
+If we wish to remove scoping for any reason we can use the +unscoped+ method. This is especially useful if a +default_scope+ is specified in the model and should not be applied for this particular query.
+
+<ruby>
+Client.unscoped.all
+</ruby>
+
+This method removes all scoping and will do a normal query on the table.
+
h3. Dynamic Finders
For every field (also known as an attribute) you define in your table, Active Record provides a finder method. If you have a field called +first_name+ on your +Client+ model for example, you get +find_by_first_name+ and +find_all_by_first_name+ for free from Active Record. If you have a +locked+ field on the +Client+ model, you also get +find_by_locked+ and +find_all_by_locked+ methods.
@@ -1119,7 +1187,8 @@ For options, please see the parent section, "Calculations":#calculations.
h3. Changelog
-* December 23 2010: Add documentation for the +scope+ method. "Ryan Bigg":http://ryanbigg.com
+* June 26 2011: Added documentation for the +scoped+, +unscoped+ and +default+ methods. "Ryan Bigg":credits.html#radar
+* December 23 2010: Add documentation for the +scope+ method. "Ryan Bigg":credits.html#radar
* April 7, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* February 3, 2010: Update to Rails 3 by "James Miller":credits.html#bensie
* February 7, 2009: Second version by "Pratik":credits.html#lifo
diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile
index 36094dcddc..50ff1c9ff7 100644
--- a/railties/guides/source/active_record_validations_callbacks.textile
+++ b/railties/guides/source/active_record_validations_callbacks.textile
@@ -182,7 +182,7 @@ It can receive an +:accept+ option, which determines the value that will be cons
<ruby>
class Person < ActiveRecord::Base
- validates :terms_of_service, :acceptance => true, :accept => 'yes'
+ validates :terms_of_service, :acceptance => { :accept => 'yes' }
end
</ruby>
@@ -338,7 +338,7 @@ WARNING. Note that the regular expression above allows a trailing newline charac
<ruby>
class Player < ActiveRecord::Base
validates :points, :numericality => true
- validates :games_played, :numericality => true, :only_integer => true
+ validates :games_played, :numericality => { :only_integer => true }
end
</ruby>
@@ -393,8 +393,8 @@ There is a +:scope+ option that you can use to specify other attributes that are
<ruby>
class Holiday < ActiveRecord::Base
- validates :name, :uniqueness => true, :scope => :year,
- :message => "should happen once per year"
+ validates :name, :uniqueness => { :scope => :year,
+ :message => "should happen once per year" }
end
</ruby>
@@ -402,7 +402,7 @@ There is also a +:case_sensitive+ option that you can use to define whether the
<ruby>
class Person < ActiveRecord::Base
- validates :name, :uniqueness => true, :case_sensitive => false
+ validates :name, :uniqueness => { :case_sensitive => false }
end
</ruby>
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index 7512f7bcb9..a0ed85cf01 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -947,7 +947,7 @@ h4. Class Attributes
h5. +class_attribute+
-The method +class_attribute+ declares one or more inheritable class attributes that can be overridden at any level down the hierarchy:
+The method +class_attribute+ declares one or more inheritable class attributes that can be overridden at any level down the hierarchy.
<ruby>
class A
@@ -983,7 +983,7 @@ self.default_params = {
}.freeze
</ruby>
-They can be also accessed and overridden at the instance level:
+They can be also accessed and overridden at the instance level.
<ruby>
A.x = 1
@@ -996,7 +996,7 @@ a1.x # => 1, comes from A
a2.x # => 2, overridden in a2
</ruby>
-The generation of the writer instance method can be prevented by setting the option +:instance_writer+ to false, as in
+The generation of the writer instance method can be prevented by setting the option +:instance_writer+ to +false+.
<ruby>
module ActiveRecord
@@ -1009,8 +1009,20 @@ end
A model may find that option useful as a way to prevent mass-assignment from setting the attribute.
+The generation of the reader instance method can be prevented by setting the option +:instance_reader+ to +false+.
+
+<ruby>
+class A
+ class_attribute :x, :instance_reader => false
+end
+
+A.x = 1 # NoMethodError
+</ruby>
+
For convenience +class_attribute+ also defines an instance predicate which is the double negation of what the instance reader returns. In the examples above it would be called +x?+.
+When +:instance_reader+ is +false+, the instance predicate returns a +NoMethodError+ just like the reader method.
+
NOTE: Defined in +active_support/core_ext/class/attribute.rb+
h5. +cattr_reader+, +cattr_writer+, and +cattr_accessor+
@@ -1036,18 +1048,24 @@ module ActionView
end
</ruby>
-we can access +field_error_proc+ in views. The generation of the writer instance method can be prevented by setting +:instance_writer+ to +false+ (not any false value, but exactly +false+):
+we can access +field_error_proc+ in views.
+
+The generation of the reader instance method can be prevented by setting +:instance_reader+ to +false+ and the generation of the writer instance method can be prevented by setting +:instance_writer+ to +false+. Generation of both methods can be prevented by setting +:instance_accessor+ to +false+. In all cases, the value must be exactly +false+ and not any false value.
<ruby>
-module ActiveRecord
- class Base
- # No pluralize_table_names= instance writer is generated.
- cattr_accessor :pluralize_table_names, :instance_writer => false
+module A
+ class B
+ # No first_name instance reader is generated.
+ cattr_accessor :first_name, :instance_reader => false
+ # No last_name= instance writer is generated.
+ cattr_accessor :last_name, :instance_writer => false
+ # No surname instance reader or surname= writer is generated.
+ cattr_accessor :surname, :instance_accessor => false
end
end
</ruby>
-A model may find that option useful as a way to prevent mass-assignment from setting the attribute.
+A model may find it useful to set +:instance_accessor+ to +false+ as a way to prevent mass-assignment from setting the attribute.
NOTE: Defined in +active_support/core_ext/class/attribute_accessors.rb+.
@@ -1146,8 +1164,12 @@ h3. Extensions to +String+
h4. Output Safety
+h5. Motivation
+
Inserting data into HTML templates needs extra care. For example you can't just interpolate +@review.title+ verbatim into an HTML page. On one hand if the review title is "Flanagan & Matz rules!" the output won't be well-formed because an ampersand has to be escaped as "&amp;amp;". On the other hand, depending on the application that may be a big security hole because users can inject malicious HTML setting a hand-crafted review title. Check out the "section about cross-site scripting in the Security guide":security.html#cross-site-scripting-xss for further information about the risks.
+h5. Safe Strings
+
Active Support has the concept of <i>(html) safe</i> strings since Rails 3. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not.
Strings are considered to be <i>unsafe</i> by default:
@@ -1173,8 +1195,6 @@ s # => "<script>...</script>"
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.
-
If you append onto a safe string, either in-place with +concat+/<tt><<</tt>, or with <tt>+</tt>, the result is a safe string. Unsafe arguments are escaped:
<ruby>
@@ -1215,6 +1235,22 @@ end
NOTE: Defined in +active_support/core_ext/string/output_safety.rb+.
+h5. Transformation
+
+As a rule of thumb, except perhaps for concatenation as explained above, any method that may change a string gives you an unsafe string. These are +donwcase+, +gsub+, +strip+, +chomp+, +underscore+, etc.
+
+In the case of in-place transformations like +gsub!+ the receiver itself becomes unsafe.
+
+INFO: The safety bit is lost always, no matter whether the transformation actually changed something.
+
+h5. Conversion and Coercion
+
+Calling +to_s+ on a safe string returns a safe string, but coercion with +to_str+ returns an unsafe string.
+
+h5. Copying
+
+Calling +dup+ or +clone+ on safe strings yields safe strings.
+
h4. +squish+
The method +squish+ strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
@@ -1460,7 +1496,15 @@ end
That may be handy to compute method names in a language that follows that convention, for example JavaScript.
-INFO: As a rule of thumb you can think of +camelize+ as the inverse of +underscore+, though there are cases where that does not hold: <tt>"SSLError".underscore.camelize</tt> gives back <tt>"SslError"</tt>.
+INFO: As a rule of thumb you can think of +camelize+ as the inverse of +underscore+, though there are cases where that does not hold: <tt>"SSLError".underscore.camelize</tt> gives back <tt>"SslError"</tt>. To support cases such as this, Active Support allows you to specify acronyms in +config/initializers/inflections.rb+:
+
+<ruby>
+ActiveSupport::Inflector.inflections do |inflect|
+ inflect.acronym 'SSL'
+end
+
+"SSLError".underscore.camelize #=> "SSLError"
+</ruby>
+camelize+ is aliased to +camelcase+.
@@ -2205,8 +2249,8 @@ The method +Array.wrap+ wraps its argument in an array unless it is already an a
Specifically:
* If the argument is +nil+ an empty list is returned.
-* Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
-* Otherwise, returns an array with the argument as its single element.
+* Otherwise, if the argument responds to +to_ary+ it is invoked, and if the value of +to_ary+ is not +nil+, it is returned.
+* Otherwise, an array with the argument as its single element is returned.
<ruby>
Array.wrap(nil) # => []
@@ -2282,7 +2326,7 @@ NOTE: Defined in +active_support/core_ext/array/grouping.rb+.
h5. +in_groups(number, fill_with = nil)+
-The method +in_groups+ splits an array into a certain number of groups. The method returns and array with the groups:
+The method +in_groups+ splits an array into a certain number of groups. The method returns an array with the groups:
<ruby>
%w(1 2 3 4 5 6 7).in_groups(3)
@@ -2714,7 +2758,7 @@ Active Support extends the method +Range#step+ so that it can be invoked without
(1..10).step(2) # => [1, 3, 5, 7, 9]
</ruby>
-As the example shows, in that case the method returns and array with the corresponding elements.
+As the example shows, in that case the method returns an array with the corresponding elements.
NOTE: Defined in +active_support/core_ext/range/blockless_step.rb+.
@@ -3316,6 +3360,32 @@ Active Support defines +Time.current+ to be today in the current time zone. That
When making Time comparisons using methods which honor the user time zone, make sure to use +Time.current+ and not +Time.now+. There are cases where the user time zone might be in the future compared to the system time zone, which +Time.today+ uses by default. This means +Time.now+ may equal +Time.yesterday+.
+h5. +all_day+, +all_week+, +all_month+, +all_quarter+ and +all_year+
+
+The method +all_day+ returns a range representing the whole day of the current time.
+
+<ruby>
+now = Time.current
+# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
+now.all_day
+# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Mon, 09 Aug 2010 23:59:59 UTC +00:00
+</ruby>
+
+Analogously, +all_week+, +all_month+, +all_quarter+ and +all_year+ all serve the purpose of generating time ranges.
+
+<ruby>
+now = Time.current
+# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
+now.all_week
+# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Sun, 15 Aug 2010 23:59:59 UTC +00:00
+now.all_month
+# => Sat, 01 Aug 2010 00:00:00 UTC +00:00..Tue, 31 Aug 2010 23:59:59 UTC +00:00
+now.all_quarter
+# => Thu, 01 Jul 2010 00:00:00 UTC +00:00..Thu, 30 Sep 2010 23:59:59 UTC +00:00
+now.all_year
+# => Fri, 01 Jan 2010 00:00:00 UTC +00:00..Fri, 31 Dec 2010 23:59:59 UTC +00:00
+</ruby>
+
h4. Time Constructors
Active Support defines +Time.current+ to be +Time.zone.now+ if there's a user time zone defined, with fallback to +Time.now+:
diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile
index 5d0dfee41c..563c1c79ae 100644
--- a/railties/guides/source/asset_pipeline.textile
+++ b/railties/guides/source/asset_pipeline.textile
@@ -3,55 +3,333 @@ h2. Asset Pipeline
This guide will cover the ideology of the asset pipeline introduced in Rails 3.1.
By referring to this guide you will be able to:
+* Understand what the asset pipeline is and what it does
* Properly organize your application assets
* Understand the benefits of the asset pipeline
-* Adding a preprocessor to the pipeline
+* Adding a pre-processor to the pipeline
* Package assets with a gem
endprologue.
h3. What Is The Asset Pipeline?
-The asset pipeline is a new feature introduced in Rails 3.1 using the "Sprockets":http://getsprockets.org/ engine. It allows developers to place design elements in +app/assets+ instead of +public+, there are many advantages to this. A big one is that they are now processed by Rails instead of your webserver, allowing you to use preprocessors like CoffeeScript, SCSS, or ERB. Another advantage is that your CSS and JavaScript is compiled into one file by default, this allows users to cache all the CSS and JavaScript data so your pages render faster. Not to mention how much cleaner your application will become.
+The asset pipeline provides a framework to concatenate and minify or compress Javascript and CSS assets. It also adds the ability to write these assets in other languages such as CoffeeScript, SCSS and ERB.
+
+Prior to Rails 3.1 these features were added through third-party Ruby libraries such as Jammit and Sprockets. Rails 3.1 includes the +sprockets-rails+ gem, which depends on the +sprockets+ gem, by default.
+
+By having this as a core feature of Rails, all developers can benefit from the power of having their assets pre-processed, compressed and minified by one central library, Sprockets. This is part of Rails' "Fast by default" strategy as outlined by DHH in his 2011 keynote at Railsconf.
+
+In new Rails 3.1 application the asset pipeline is enable by default. It can be disabled in +application.rb+ by putting this line inside the +Application+ class definition:
+
+<plain>
+ config.assets.enabled = false
+</plain>
+
+It is recommended that you use the defaults for all new apps.
+
+
+h4. Main Features
+
+The first is to concatenate of assets. This is important in a production environment to reduce the number of requests that a client browser has to make to render a web page. While Rails already has a feature to concatenate these types of asset--by placing +:cache => true+ at the end of tags such as +javascript_include_tag+ and +stylesheet_link_tag+--, many people do not use it.
+
+The default behavior in Rails 3.1 and onward is to concatenate all files into one master file each for JS and CSS, however you can separate files or groups of files if required (see below). In production an MD5 fingerprint is inserted into each filename.
+
+The second feature of the pipeline is to minify or compress. For CSS this usually involves removing whitespace and comments. For Javascript more complex processes can be applied.
+
+You can choose from a set of built in options or specify your own.
+
+The third feature is the ability to code these assets using another language, or language extension. These include SCSS or Sass for CSS, CoffeeScript for Javascript, and ERB for both.
+
+h4. What is fingerprinting and why should I care?
+
+Fingerprinting is a technique where the filenames of content that is static or infrequently updated is altered to be unique to the content contained in the file.
+
+When a filename is unique and based on its content, http headers can be set to encourage caches everywhere (at ISPs, in browsers) to keep there own copy of the content. When the content is updated, the fingerprint will change and the remote clients will request the new file. This is generally known as _cachebusting_.
+
+The most effective technique is to insert a hash of the content into the name, usually at the end. For example a CSS file +global.css+ is hashed and the filename is updated to incorporate the hash.
+
+<plain>
+global.css => global-908e25f4bf641868d8683022a5b62f54.css
+</plain>
+
+This is the strategy adopted by the Rails asset pipeline.
+
+Rails old strategy was to append a query string to every asset linked with a built-in helper. In the source the generated code looked like this:
+
+<plain>
+/stylesheets/global.css?1309495796
+</plain>
+
+This has several disadvantages:
+
+1. Not all caches will cache content with a query string
+
+"Steve Souders recommends":http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/, "...avoiding a querystring for cacheable resources". He found that in these case 5-20% of requests will not be cached.
+
+2. The filename can change between nodes in multi-server environments.
+
+The query string in Rails is based on the files mtime (mtime is the file modification time). When assets are deployed to a cluster, there is no guarantee that the timestamps will be the same, resulting in different values being used depending on which server handles the request.
+
+The other problems is that when static assets are deployed with each new release of code, the mtime of *all* these files changes, forcing all remote clients to fetch them again, even when the content of those assets has not changed.
+
+Fingerprinting avoids all these problems be ensuring filenames are consistent based on the content.
+
+More reading:
+
+* "Optimize caching":http://code.google.com/speed/page-speed/docs/caching.html
+* "Revving Filenames: don’t use querystring":http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/
+
h3. How to Use the Asset Pipeline
-The asset pipeline is easy to migrate to and use. There are a few things that you'll need to learn first, like where to place your files, how to create a manifest, and how to add any preproccesors if you desire.
+In previous versions of Rails, all assets were located in subdirectories of +public+ such as +images+, +javascripts+ and +stylesheets+. With the asset pipeline, the preferred location for these assets is now the +app/assets+ directory. Files in this directory will be served by the Sprockets middleware included in the sprockets gem.
+
+This is not to say that assets can (or should) no longer be placed in +public+. They still can be and will be served as static files by the application or web server. You would only use +app/assets+ if you wish your files to undergo some pre-processing before they are served.
+
+When a scaffold or controller is generated for the application, Rails will also generate a JavaScript file (or CoffeeScript if the +coffee-script+ gem is in the +Gemfile+) and a Cascading Style Sheet file (or SCSS if +sass-rails+ is in the +Gemfile+) file for that controller.
+
+For example, if a +ProjectsController+ is generated, there will be a new file at +app/assets/javascripts/projects.js.coffee+ and another at +app/assets/stylesheets/projects.css.scss+. You should put any JavaScript or CSS unique to a controller inside their respective asset files, as these files can then be loaded just for these controllers with lines such as +<%= javascript_include_tag params[:controller] %>+ or +<%= stylesheet_link_tag params[:controller] %>+.
h4. Asset Organization
-WIP
+Assets can be placed inside an application in one of three locations: +app/assets+, +lib/assets+ or +vendor/assets+.
+
++app/assets+ is for assets that are owned by the application, such as custom images, JavaScript files or stylesheets.
+
++lib/assets+ is for your own libraries' code that doesn't really fit into the scope of the application or those libraries which are shared across applications.
+
++vendor/assets+ is for assets that are owned by outside entities, such as code for JavaScript plugins.
+
+All subdirectories that exists within these three locations will be added to the search path for Sprockets (visible by calling +Rails.application.config.assets.paths+ in a console). When an asset is requested, these paths will be looked through to see if they contain an asset matching the name specified. Once an asset has been found, it's processed by Sprockets and served.
+
+h4. Coding links to Assets
+
+To access assets, we can use the same tags that we are generally familiar with:
+
+<erb>
+ <%= image_tag "rails.png" %>
+</erb>
+
+Providing that assets are enabled within our application (+config.assets.enabled+ in the current environment's file is not set to +false+), this file will be served by Sprockets unless a file at +public/assets/rails.png+ exists, in which case that file will be served. Alternatively, a file with an MD5 hash after its name such as +public/assets/rails-af27b6a414e6da00003503148be9b409.png+ will also be picked up by Sprockets. How these hashes are generated is covered in the "Production Assets":#production_assets section later on in this guide.
+
+Otherwise, Sprockets will look through the available paths until it finds a file that matches the name and then will serve it, first looking in the application's assets directories and then falling back to the various engines of the application.
+
+Sprockets does not add any new methods to require your assets, we still use the familiar +javascript_include_tag+ and +stylesheet_link_tag+.
+
+<erb>
+ <%= stylesheet_link_tag "application" %>
+ <%= javascript_include_tag "application" %>
+</erb>
+
+These helpers (when the pipeline is on) are providing links to the compiled manifest with the specified name (or names).
+
+h4. Manifest Files and Directives
+
+Sprockets uses manifest files to determine which assets to include and serve. These manifest files contain _directives_ - instructions that tell Sprockets which files to require in order to build a single CSS or JavaScript file. With these directives, Sprockets will load the files specified, process them if necessary, concatenate them into one single file and then compress them (if +Rails.application.config.assets.compress+ is set to +true+). By serving one file rather than many, a page's load time is greatly reduced.
+
+For example, in the default Rails application there's a +app/assets/javascripts/application.js+ file which contains the following lines:
+
+<plain>
+//= require jquery
+//= require jquery_ujs
+//= require_tree .
+</plain>
+
+In JavaScript files, directives begin with +//=+. In this case, the following file is using the +require+ directive and the +require_tree+ directive. The +require+ directive tells Sprockets that we would like to require a file called +jquery.js+ that is available somewhere in the search path for Sprockets. By default, this is located inside the +vendor/assets/javascripts+ directory contained within the +jquery-rails+ gem. An identical event takes place for the +jquery_ujs+ require
+
+The +require_tree .+ directive tells Sprockets to include _all_ JavaScript files in this directory into the output. Only a path relative to the file can be specified.
+
+There's also a default +app/assets/stylesheets/application.css+ file which contains these lines:
+
+<plain>
+/* ...
+*= require_self
+*= require_tree .
+*/
+</plain>
+
+The directives that work in the JavaScript files will also work in stylesheets, obviously including stylesheets rather than JavaScript files. The +require_tree+ directive here works the same way as the JavaScript one, requiring all stylesheets from the current directory.
+
+In this example +require_self+ is used. This will put the CSS contained within the file (if any) at the top of any other CSS in this file unless +require_self+ is specified after another +require+ directive.
+
+You can have as many manifest files as you need. For example the +admin.css+ and +admin.js+ manifest could contain the JS and CSS files that are used for the admin section of an application.
+
+For some assets (like CSS) the compiled order is important. You can specify individual files and they will be compiled in the order specified:
+
+<plain>
+/* ...
+*= require reset
+*= require layout
+*= require chrome
+*/
+</plain>
+
+
+h4. Preprocessing
+
+The file extensions used on an asset will determine what preprocssing will be applied. When a controller or a scaffold is generated with the default Rails gemset, a CoffeeScript file and a SCSS file will be generated in place of a regular JavaScript and CSS file. The example used before was a controller called "projects", which generated an +app/assets/javascripts/projects.js.coffee+ and a +app/assets/stylesheets/projects.css.scss+ file.
+
+When these files are requested, they will be processed by the processors provided by the +coffee-script+ and +sass-rails+ gems and then sent back to the browser as JavaScript and CSS respectively.
+
+Additional layers of pre-processing can be requested by adding other extensions. These should be used in the order the processing should be applied. For example, a stylesheet called +app/assets/stylesheets/projects.css.scss.erb+ would first be processed as ERB, then SCSS and finally served as CSS. The same applies to a JavaScript file - +app/assets/javascripts/projects.js.coffee.erb+ would be process as ERB, CoffeeScript and served as JavaScript.
+
+Keep in mind that the order of these pre-processors is important. For example, if we called our JavaScript file +app/assets/javascripts/projects.js.erb.coffee+ then it would be processed with the CoffeeScript interpreter first, which wouldn't understand ERB and therefore we would run into problems.
+
+h3. In Development
+
+TODO: Talk about: Rack::Cache's caching (used in dev and production. The only difference is hashing and headers).
+
+In the development environment assets are compiled and cached on the first request after the server is started. Sprockets sets a +must-validate+ cache-control http header to reduce request overhead on subsequent requests - on these the browser gets a 304 (not-modified) response.
+
+If any of the files in the manifest have changed between requests, the server will respond with a new compiled file.
+
+h4. Debugging Assets
+
+You can put +?debug_assets=true+ or +?debug_assets=1+ at the end of a URL and Sprockets will expand the lines which load the assets. For example, if we had an +app/assets/javascripts/application.js+ file containing these lines:
+
+<plain>
+//= require "projects"
+//= require "tickets"
+</plain>
+
+By default, this would only render this line when used with +<%= javascript_include_tag "application" %>+ in a view or layout:
+
+<html>
+ <script src='/assets/application.js'></script>
+</html>
+
+When the +debug_assets+ parameter is set, this line will be expanded out into three separate lines, separating out the combined file into their parts.
+
+<html>
+ <script src='/assets/application.js'></script>
+ <script src='/assets/projects.js'></script>
+ <script src='/assets/tickets.js'></script>
+</html>
+
+This allows the individual parts of an asset to be rendered and debugged separately.
+
+h3. In Production
+
+In the production environment, assets are served slightly differently.
+
+On the first request the assets are compiled and cached as described above, however the manifest names are altered to include an MD5 hash. Files names typically will look like these:
+
+<plain>
+/assets/application-908e25f4bf641868d8683022a5b62f54.js
+/assets/application-4dd5b109ee3439da54f5bdfd78a80473.css
+</plain>
+
+The MD5 is generated from the contents of the compiled files, and is included in the http +Content-MD5+ header.
+
+Sprockets also sets the +Cache-Control+ http header to +max-age=31536000+. This signals all caches between your server and the client browser that this content (the file served) can be cached for 1 year. The effect of this is to reduce the number of requests for this asset from your server; the asset has a good chance of being in the local browser cache or some intermediate cache.
+
+This behavior is controlled by the setting of +config.action_controller.perform_caching+ setting in Rails (which is +true+ for production, +false+ for everything else). This value is propagated to Sprockets during initialization for use when action_controller is not available.
+
+TODO:
+describe each and the differences between:
+ * Sass-rails's handy +image_url+ helpers
+ * ERB pre-processing and +asset_path+
+
+h4. Precompiling assets
+
+Even though assets are served by Rack::Cache with far-future headers, in high traffic sites this may not be fast enough.
+
+Rails comes bundled with a rake task to compile the manifests to files on disc. These are located in the +public/assets+ directory where they will be served by your web server instead of the Rails application.
+
+TODO: Add section about image assets
+
+The rake task is:
+
+<erb>
+rake assets:precompile
+</erb>
+
+TODO: explain where to use this with Capistrano
+
+TODO: talk about the +config.assets.precompile+ option and the default matcher for files:
+
+<erb>
+[ /\w+\.(?!js|css).+/, "application.js", "application.css" ]
+</erb>
+
+
+Sprockets also creates a "gzip":http://en.wikipedia.org/wiki/Gzip (.gz) of your assets. This prevents your server from contently compressing your assets for each request. You must configure your server to use gzip compression and serve the compressed assets that will be stored in the public/assets folder. The following are some configuration blocks that you can use for common servers.
+NGINX & Apache examples?
+
+
+
+h3. Customizing The Pipeline
+
+h4. CSS
+
+There is currently one option for processing CSS - SCSS. This Gem extends the CSS syntax and offers minification.
+
+The following line will enable SCSS in you project.
+
+<erb>
+config.assets.css_compressor = :scss
+</erb>
+
+This option is for compression only and does not relate to the SCSS language extensions that apply when using the +.scss+ file extension on CSS assets.
+
+h4. Javascript
+
+There are three options available to process javascript - uglifier, closure and yui.
+
+The default Gemfile includes "uglifier":https://github.com/lautis/uglifier. This gem wraps "UglifierJS":https://github.com/mishoo/UglifyJS (written for NodeJS) in Ruby. It compress your code by removing white spaces and other magical things like changing your if and else statements to ternary operators when possible.
+
+TODO: Add detail about the other two
+
+The following line will invoke uglifier for Javascript compression.
+
+<erb>
+config.assets.js_compressor = :uglifier
+</erb>
+
+
+
+h4. Using your own compressor
+
+The compressor config settings for CSS and Javascript will also take an Object.
-Sprockets will automatically load manifest files by searching directories in app/assets and including the first file with a basename of index. (Confirm and add: does it load app/assets/index?)
+This object must have a +compress+ method that takes a string as the sole argument and it must return a string.
-h4. Directives
+<erb>
+class Transformer
+ def compress(string)
+ do_something_returning_a_string(string)
+ end
+end
+</erb>
-WIP
+To enable this pass a +new+ Object to the config option in +application.rb+:
-Sprockets, the rails tie that powers the asset pipeline, provides three directives which are like Ruby's methods. They are: +require+, +require_tree+, and +require_self+. These directives must be called at the top of a file in a comment with an equal sign before it. (note: CSS directives need *= if in a continuous comment -- confirm please)
+<erb>
+config.assets.css_compressor = Transformer.new
+</erb>
-The require directive loads a file with the supplied basename from the following paths: app/assets/*, lib/assets/*, vendor/assets/*, as well as any of your gem's asset files.
-Require tree does...
+h4. Changing the _assets_ path
-Require self does...
+The public path that Sprockets uses by default is +/assets+.
-h4. Stacking Preprocessors
+This can be changed to something else:
-Sprockets allows you to stack preprocessors. The stack is ran off the file extensions in a last in, first out method (like popping an array). For example if we want to make a JavaScript asset with both CoffeeScript and ERB the file would be named: +name.js.coffee.erb+. If it were named +name.js.erb.coffee+ CoffeeScript would raise an error because it doesn't understand ERB tags.
+<erb>
+config.assets.prefix = "/some_other_path"
+</erb>
-h4. Adding a Preproccessor
+This is a handy option if you have any existing project (pre Rails 3.1) that already uses this path.
-WIP
-https://github.com/rtomayko/tilt for gems or config.register_processor('text/css', MyAwesomeProccessor) for local stuff
+h3. Adding Assets to Your Gems
-h3. Packaging Assets with Your Gems
+Assets can also come from external sources in the form of gems.
-You may find it useful to package certain assets with your gem. A good example would be the "pjax_rails":https://github.com/rails/pjax_rails/ gem. This gem bundles the latest "PJAX":https://github.com/defunkt/jquery-pjax library and some helper methods. If you take a look at the source of pjax_rails, you'll see that it bundles the assets in +lib/assets+ just the same way as you would in +app/assets+. Doing so allows pjax_rails to update JavaScripts without asking users to copy them into their public folder
+A good example of this is the +jquery-rails+ gem which comes with Rails as the standard JavaScript library gem. This gem contains an engine class which inherits from +Rails::Engine+. By doing this, Rails is informed that the directory for this gem may contain assets and the +app/assets+, +lib/assets+ and +vendor/assets+ directories of this engine are added to the search path of Sprockets.
-If you want the user to load your JavaScript files in their template, you will have to ask them to add a directive to do so. Also avoid any common names such as +form_check.js+ instead try using +mygem/form_check.js+ so it's clear where it's coming from. This will also make it unlikely that your users will create a file with the same name causing the asset pipeline to choose the user's file over yours.
+h3. Making Your Library or Gem a Pre-Processor
-h3. More on Sprockets
+"You should be able to register [your gems] on Tilt and Sprockets will find them." - Josh
+Tilt: https://github.com/rtomayko/tilt
-Sprockets is the engine that handles the asset pipeline in Rails 3.1 and above. Their official website is available at "http://getsprockets.org/":http://getsprockets.org/ and the source code is "available on github":https://github.com/sstephenson/sprockets.
diff --git a/railties/guides/source/association_basics.textile b/railties/guides/source/association_basics.textile
index 458bfefad8..3c2497e83a 100644
--- a/railties/guides/source/association_basics.textile
+++ b/railties/guides/source/association_basics.textile
@@ -1120,11 +1120,9 @@ h6(#has_many-collection-find). <tt><em>collection</em>.find(...)</tt>
The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+.
<ruby>
-@open_orders = @customer.orders.all(:conditions => "open = 1")
+@open_orders = @customer.orders.where(:open => 1)
</ruby>
-NOTE: Starting Rails 3, supplying options to +ActiveRecord::Base.find+ method is discouraged. Use <tt><em>collection</em>.where</tt> instead when you need to pass conditions.
-
h6(#has_many-collection-where). <tt><em>collection</em>.where(...)</tt>
The <tt><em>collection</em>.where</tt> method finds objects within the collection based on the conditions supplied but the objects are loaded lazily meaning that the database is queried only when the object(s) are accessed.
diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile
index f058dce42b..252003edd0 100644
--- a/railties/guides/source/caching_with_rails.textile
+++ b/railties/guides/source/caching_with_rails.textile
@@ -382,6 +382,7 @@ class ProductsController < ApplicationController
# anything. The default render checks for this using the parameters
# used in the previous call to stale? and will automatically send a
# :not_modified. So that's it, you're done.
+ end
end
</ruby>
diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile
index 5fe9ad101b..9e3b25d794 100644
--- a/railties/guides/source/command_line.textile
+++ b/railties/guides/source/command_line.textile
@@ -5,7 +5,7 @@ Rails comes with every command line tool you'll need to
* Create a Rails application
* Generate models, controllers, database migrations, and unit tests
* Start a development server
-* Mess with objects through an interactive shell
+* Experiment with objects through an interactive shell
* Profile and benchmark your new creation
endprologue.
@@ -51,15 +51,13 @@ $ rails new commandsapp
Rails will set you up with what seems like a huge amount of stuff for such a tiny command! You've got the entire Rails directory structure now with all the code you need to run our simple application right out of the box.
-INFO: This output will seem very familiar when we get to the +generate+ command. Creepy foreshadowing!
-
h4. +rails server+
-The +rails server+ command launches a small web server named WEBrick which comes bundled with Ruby. You'll use this any time you want to view your work through a web browser.
+The +rails server+ command launches a small web server named WEBrick which comes bundled with Ruby. You'll use this any time you want to access your application through a web browser.
-INFO: WEBrick isn't your only option for serving Rails. We'll get to that in a later section.
+INFO: WEBrick isn't your only option for serving Rails. We'll get to that "later":#different-servers.
-Without any prodding of any kind, +rails server+ will run our new shiny Rails app:
+With no further work, +rails server+ will run our new shiny Rails app:
<shell>
$ cd commandsapp
@@ -77,13 +75,19 @@ With just three commands we whipped up a Rails server listening on port 3000. Go
You can also use the alias "s" to start the server: <tt>rails s</tt>.
+The server can be run on a different port using the +-p+ option. The default development environment can be changed using +-e+.
+
+<shell>
+$ rails server -e production -p 4000
+</shell>
+
h4. +rails generate+
-The +rails generate+ command uses templates to create a whole lot of things. You can always find out what's available by running +rails generate+ by itself. Let's do that:
+The +rails generate+ command uses templates to create a whole lot of things. Running +rails generate+ by itself gives a list of available generators:
<shell>
$ rails generate
-Usage: rails generate generator [args] [options]
+Usage: rails generate GENERATOR [args] [options]
...
...
@@ -99,7 +103,7 @@ Rails:
NOTE: You can install more generators through generator gems, portions of plugins you'll undoubtedly install, and you can even create your own!
-Using generators will save you a large amount of time by writing *boilerplate code*, code that is necessary for the app to work, but not necessary for you to spend time writing. That's what we have computers for.
+Using generators will save you a large amount of time by writing *boilerplate code*, code that is necessary for the app to work.
Let's make our own controller with the controller generator. But what command should we use? Let's ask the generator:
@@ -148,7 +152,8 @@ $ rails generate controller Greetings hello
create test/unit/helpers/greetings_helper_test.rb
invoke assets
create app/assets/javascripts/greetings.js
- create app/assets/stylesheets/greetings.css
+ invoke css
+ create app/assets/stylesheets/greetings.css
</shell>
@@ -171,7 +176,7 @@ Then the view, to display our message (in +app/views/greetings/hello.html.erb+):
<p><%= @message %></p>
</html>
-Deal. Go check it out in your browser. Fire up your server using +rails server+.
+Fire up your server using +rails server+.
<shell>
$ rails server
@@ -184,7 +189,7 @@ The URL will be "http://localhost:3000/greetings/hello":http://localhost:3000/gr
INFO: With a normal, plain-old Rails application, your URLs will generally follow the pattern of http://(host)/(controller)/(action), and a URL like http://(host)/(controller) will hit the *index* action of that controller.
-Rails comes with a generator for data models too:
+Rails comes with a generator for data models too.
<shell>
$ rails generate model
@@ -288,11 +293,7 @@ You can also use the alias "db" to invoke the dbconsole: <tt>rails db</tt>.
h4. +rails plugin+
-The +rails plugin+ command simplifies plugin management; think a miniature version of the Gem utility. Let's walk through installing a plugin. You can call the sub-command +discover+, which sifts through repositories looking for plugins, or call +source+ to add a specific repository of plugins, or you can specify the plugin location directly.
-
-Let's say you're creating a website for a client who wants a small accounting system. Every event having to do with money must be logged, and must never be deleted. Wouldn't it be great if we could override the behavior of a model to never actually take its record out of the database, but instead, just set a field?
-
-There is such a thing! The plugin we're installing is called +acts_as_paranoid+, and it lets models implement a +deleted_at+ column that gets set when you call destroy. Later, when calling find, the plugin will tack on a database check to filter out "deleted" things.
+The +rails plugin+ command simplifies plugin management. Plugins can be installed by name or their repository URLs. You need to have Git installed if you want to install a plugin from a Git repo. The same holds for Subversion too.
<shell>
$ rails plugin install https://github.com/technoweenie/acts_as_paranoid.git
@@ -310,6 +311,12 @@ h4. +rails runner+
$ rails runner "Model.long_running_method"
</shell>
+You can specify the environment in which the +runner+ command should operate using the +-e+ switch.
+
+<shell>
+$ rails runner -e staging "Model.long_running_method"
+</shell>
+
h4. +rails destroy+
Think of +destroy+ as the opposite of +generate+. It'll figure out what generate did, and undo it.
@@ -388,13 +395,56 @@ h4. +db+
The most common tasks of the +db:+ Rake namespace are +migrate+ and +create+, and it will pay off to try out all of the migration rake tasks (+up+, +down+, +redo+, +reset+). +rake db:version+ is useful when troubleshooting, telling you the current version of the database.
+More information about migrations can be found in the "Migrations":migrations.html guide.
+
h4. +doc+
-If you want to strip out or rebuild any of the Rails documentation (including this guide!), the +doc:+ namespace has the tools. Stripping documentation is mainly useful for slimming your codebase, like if you're writing a Rails application for an embedded platform.
+The +doc:+ namespace has the tools to generate documentation for your app, API documentation, guides. Documentation can also be stripped which is mainly useful for slimming your codebase, like if you're writing a Rails application for an embedded platform.
+
+* +rake doc:app+ generates documentation for your application in +doc/app+.
+* +rake doc:guides+ generates Rails guides in +doc/guides+.
+* +rake doc:rails+ generates API documentation for Rails in +doc/api+.
+* +rake doc:plugins+ generates API documentation for all the plugins installed in the application in +doc/plugins+.
+* +rake doc:clobber_plugins+ removes the generated documentation for all plugins.
h4. +notes+
-These tasks will search through your code for commented lines beginning with "FIXME", "OPTIMIZE", "TODO", or any custom annotation (like XXX) and show you them.
++rake notes+ will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is only done in files with extension +.builder+, +.rb+, +.rxml+, +.rhtml+ and +.erb+ for both default and custom annotations.
+
+<shell>
+$ rake notes
+(in /home/foobar/commandsapp)
+app/controllers/admin/users_controller.rb:
+ * [ 20] [TODO] any other way to do this?
+ * [132] [FIXME] high priority for next deploy
+
+app/model/school.rb:
+ * [ 13] [OPTIMIZE] refactor this code to make it faster
+ * [ 17] [FIXME]
+</shell>
+
+If you are looking for a specific annotation, say FIXME, you can use +rake notes:fixme+. Note that you have to lower case the annotation's name.
+
+<shell>
+$ rake notes:fixme
+(in /home/foobar/commandsapp)
+app/controllers/admin/users_controller.rb:
+ * [132] high priority for next deploy
+
+app/model/school.rb:
+ * [ 17]
+</shell>
+
+You can also use custom annotations in your code and list them using +rake notes:custom+ by specifying the annotation using an environment variable +ANNOTATION+.
+
+<shell>
+$ rake notes:custom ANNOTATION=BUG
+(in /home/foobar/commandsapp)
+app/model/post.rb:
+ * [ 23] Have to fix this one before pushing!
+</shell>
+
+NOTE. When using specific annotations and custom annotations, the annotation name (FIXME, BUG etc) is not displayed in the output lines.
h4. +routes+
@@ -457,7 +507,7 @@ We had to create the *gitapp* directory and initialize an empty git repository b
<shell>
$ cat config/database.yml
-# PostgreSQL. Versions 7.4 and 8.x are supported.
+# PostgreSQL. Versions 8.2 and up are supported.
#
# Install the ruby-postgres driver:
# gem install ruby-postgres
@@ -478,11 +528,13 @@ development:
...
</shell>
-It also generated some lines in our database.yml configuration corresponding to our choice of PostgreSQL for database. The only catch with using the SCM options is that you have to make your application's directory first, then initialize your SCM, then you can run the +rails new+ command to generate the basis of your app.
+It also generated some lines in our database.yml configuration corresponding to our choice of PostgreSQL for database.
-h4. +server+ with Different Backends
+NOTE. The only catch with using the SCM options is that you have to make your application's directory first, then initialize your SCM, then you can run the +rails new+ command to generate the basis of your app.
-Many people have created a large number different web servers in Ruby, and many of them can be used to run Rails. Since version 2.3, Rails uses Rack to serve its webpages, which means that any webserver that implements a Rack handler can be used. This includes WEBrick, Mongrel, Thin, and Phusion Passenger (to name a few!).
+h4(#different-servers). +server+ with Different Backends
+
+Many people have created a large number of different web servers in Ruby, and many of them can be used to run Rails. Since version 2.3, Rails uses Rack to serve its webpages, which means that any webserver that implements a Rack handler can be used. This includes WEBrick, Mongrel, Thin, and Phusion Passenger (to name a few!).
NOTE: For more details on the Rack integration, see "Rails on Rack":rails_on_rack.html.
@@ -504,97 +556,3 @@ $ rails server mongrel
=> Rails 3.1.0 application starting on http://0.0.0.0:3000
...
</shell>
-
-h4. The Rails Generation: Generators
-
-INFO: For a good rundown on generators, see "Understanding Generators":http://wiki.rubyonrails.org/rails/pages/UnderstandingGenerators. A lot of its material is presented here.
-
-Generators are code that generates code. Let's experiment by building one. Our generator will generate a text file.
-
-The Rails generator by default looks in these places for available generators, where Rails.root is the root of your Rails application, like /home/foobar/commandsapp:
-
-* Rails.root/lib/generators
-* Rails.root/vendor/generators
-* Inside any plugin with a directory like "generators" or "rails_generators"
-* ~/.rails/generators
-* Inside any Gem you have installed with a name ending in "_generator"
-* Inside any Gem installed with a "rails_generators" path, and a file ending in "_generator.rb"
-* Finally, the builtin Rails generators (controller, model, mailer, etc.)
-
-Let's try the fourth option (in our home directory), which will be easy to clean up later:
-
-<shell>
-$ mkdir -p ~/.rails/generators/tutorial_test/templates
-$ touch ~/.rails/generators/tutorial_test/templates/tutorial.erb
-$ touch ~/.rails/generators/tutorial_test/tutorial_test_generator.rb
-</shell>
-
-We'll fill +tutorial_test_generator.rb+ out with:
-
-<ruby>
-class TutorialTestGenerator < Rails::Generator::Base
- def initialize(*runtime_args)
- super(*runtime_args)
- @tut_args = runtime_args
- end
-
- def manifest
- record do |m|
- m.directory "public"
- m.template "tutorial.erb", File.join("public", "tutorial.txt"),
- :assigns => { :args => @tut_args }
- end
- end
-end
-</ruby>
-
-We take whatever args are supplied, save them to an instance variable, and literally copying from the Rails source, implement a +manifest+ method, which calls +record+ with a block, and we:
-
-* Check there's a *public* directory. You bet there is.
-* Run the ERB template called "tutorial.erb".
-* Save it into "Rails.root/public/tutorial.txt".
-* Pass in the arguments we saved through the +:assigns+ parameter.
-
-Next we'll build the template:
-
-<shell>
-$ cat ~/.rails/generators/tutorial_test/templates/tutorial.erb
-I'm a template!
-
-I got assigned some args:
-<%= require 'pp'; PP.pp(args, "") %>
-</shell>
-
-Then we'll make sure it got included in the list of available generators:
-
-<shell>
-$ rails generate
-...
-...
-Installed Generators
- User: tutorial_test
-</shell>
-
-SWEET! Now let's generate some text, yeah!
-
-<shell>
-$ rails generate tutorial_test arg1 arg2 arg3
- exists public
- create public/tutorial.txt
-</shell>
-
-And the result:
-
-<shell>
-$ cat public/tutorial.txt
-I'm a template!
-
-I got assigned some args:
-[["arg1", "arg2", "arg3"],
- {:collision=>:ask,
- :quiet=>false,
- :generator=>"tutorial_test",
- :command=>:create}]
-</shell>
-
-Tada!
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index da951a0833..8e6010ff79 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -98,7 +98,7 @@ NOTE. The +config.asset_path+ configuration is ignored if the asset pipeline is
* +config.secret_token+ used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get +config.secret_token+ initialized to a random key in +config/initializers/secret_token.rb+.
-* +config.serve_static_assets+ configures Rails to serve static assets. Defaults to true, but in the production environment is turned off. The server software used to run the application should be used to serve the assets instead.
+* +config.serve_static_assets+ configures Rails itself to serve static assets. Defaults to true, but in the production environment is turned off as the server software (e.g. Nginx or Apache) used to run the application should serve static assets instead. Unlike the default setting set this to true when running (absolutely not recommended!) or testing your app in production mode using WEBrick. Otherwise you won´t be able use page caching and requests for files that exist regularly under the public directory will anyway hit your Rails app.
* +config.session_store+ is usually set up in +config/initializers/session_store.rb+ and specifies what class to use to store the session. Possible values are +:cookie_store+ which is the default, +:mem_cache_store+, and +:disabled+. The last one tells Rails not to deal with sessions. Custom session stores can also be specified:
@@ -116,8 +116,23 @@ WARNING: Threadsafe operation is incompatible with the normal workings of develo
* +config.whiny_nils+ enables or disables warnings when a certain set of methods are invoked on +nil+ and it does not respond to them. Defaults to true in development and test environments.
+h4. Configuring Assets
+
+Rails 3.1, by default, is set up to use the +sprockets+ gem to manage assets within an application. This gem concatenates and compresses assets in order to make serving them much less painful.
+
+* +config.assets.css_compressor+ defines the CSS compressor to use. Only supported value at the moment is +:yui+, which uses the +yui-compressor+ gem.
+
* +config.assets.enabled+ a flag that controls whether the asset pipeline is enabled. It is explicitly initialized in +config/application.rb+.
+* +config.assets.js_compressor+ defines the JavaScript compressor to use. Possible values are +:closure+, +:uglifier+ and +:yui+ which require the use of the +closure-compiler+, +uglifier+ or +yui-compressor+ gems respectively.
+
+* +config.assets.paths+ contains the paths which are used to look for assets. Appending paths to this configuration option will cause those paths to be used in the search for assets.
+
+* +config.assets.precompile+ allows you to specify additional assets (other than +application.css+ and +application.js+) which are to be precompiled when +rake assets:precompile+ is run.
+
+* +config.assets.prefix+ defines the prefix where assets are served from. Defaults to +/assets+.
+
+
h4. Configuring Generators
Rails 3 allows you to alter what generators are used with the +config.generators+ method. This method takes a block:
@@ -220,21 +235,21 @@ h4. Configuring Active Record
* +config.active_record.table_name_suffix+ lets you set a global string to be appended to table names. If you set this to +_northwest+, then the Customer class will look for +customers_northwest+ as its table. The default is an empty string.
-* +config.active_record.pluralize_table_names+ specifies whether Rails will look for singular or plural table names in the database. If set to +true+ (the default), then the Customer class will use the +customers+ table. If set to +false+, then the Customer class will use the +customer+ table.
+* +config.active_record.pluralize_table_names+ specifies whether Rails will look for singular or plural table names in the database. If set to true (the default), then the Customer class will use the +customers+ table. If set to false, then the Customer class will use the +customer+ table.
* +config.active_record.default_timezone+ determines whether to use +Time.local+ (if set to +:local+) or +Time.utc+ (if set to +:utc+) when pulling dates and times from the database. The default is +:utc+ for Rails, although Active Record defaults to +:local+ when used outside of Rails.
* +config.active_record.schema_format+ controls the format for dumping the database schema to a file. The options are +:ruby+ (the default) for a database-independent version that depends on migrations, or +:sql+ for a set of (potentially database-dependent) SQL statements.
-* +config.active_record.timestamped_migrations+ controls whether migrations are numbered with serial integers or with timestamps. The default is +true+, to use timestamps, which are preferred if there are multiple developers working on the same application.
+* +config.active_record.timestamped_migrations+ controls whether migrations are numbered with serial integers or with timestamps. The default is true, to use timestamps, which are preferred if there are multiple developers working on the same application.
-* +config.active_record.lock_optimistically+ controls whether Active Record will use optimistic locking. By default this is +true+.
+* +config.active_record.lock_optimistically+ controls whether Active Record will use optimistic locking and is true by default.
* +config.active_record.whitelist_attributes+ will create an empty whitelist of attributes available for mass-assignment security for all models in your app.
The MySQL adapter adds one additional configuration option:
-* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether Active Record will consider all +tinyint(1)+ columns in a MySQL database to be booleans. By default this is +true+.
+* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether Active Record will consider all +tinyint(1)+ columns in a MySQL database to be booleans and is true by default.
The schema dumper adds one additional configuration option:
@@ -260,7 +275,7 @@ h4. Configuring Action Controller
* +config.action_controller.request_forgery_protection_token+ sets the token parameter name for RequestForgery. Calling +protect_from_forgery+ sets it to +:authenticity_token+ by default.
-* +config.action_controller.allow_forgery_protection+ enables or disables CSRF protection. By default this is +false+ in test mode and +true+ in all other modes.
+* +config.action_controller.allow_forgery_protection+ enables or disables CSRF protection. By default this is false in test mode and true in all other modes.
* +config.action_controller.relative_url_root+ can be used to tell Rails that you are deploying to a subdirectory. The default is +ENV['RAILS_RELATIVE_URL_ROOT']+.
@@ -330,7 +345,7 @@ And can reference in the view with the following code:
<%= stylesheet_link_tag :special %>
</ruby>
-* +ActionView::Helpers::AssetTagHelper::AssetPaths.cache_asset_ids+ With the cache enabled, the asset tag helper methods will make fewer expensive file system calls (the default implementation checks the file system timestamp). However this prevents you from modifying any asset files while the server is running.
+* +config.action_view.cache_asset_ids+ With the cache enabled, the asset tag helper methods will make fewer expensive file system calls (the default implementation checks the file system timestamp). However this prevents you from modifying any asset files while the server is running.
h4. Configuring Action Mailer
@@ -350,11 +365,11 @@ There are a number of settings available on +config.action_mailer+:
** +:location+ - The location of the sendmail executable. Defaults to +/usr/sbin/sendmail+.
** +:arguments+ - The command line arguments. Defaults to +-i -t+.
-* +config.action_mailer.raise_delivery_errors+ specifies whether to raise an error if email delivery cannot be completed. It defaults to +true+.
+* +config.action_mailer.raise_delivery_errors+ specifies whether to raise an error if email delivery cannot be completed. It defaults to true.
* +config.action_mailer.delivery_method+ defines the delivery method. The allowed values are +:smtp+ (default), +:sendmail+, and +:test+.
-* +config.action_mailer.perform_deliveries+ specifies whether mail will actually be delivered. By default this is +true+; it can be convenient to set it to +false+ for testing.
+* +config.action_mailer.perform_deliveries+ specifies whether mail will actually be delivered and is true by default. It can be convenient to set it to false for testing.
* +config.action_mailer.default+ configures Action Mailer defaults. These default to:
<ruby>
@@ -366,12 +381,12 @@ There are a number of settings available on +config.action_mailer+:
* +config.action_mailer.observers+ registers observers which will be notified when mail is delivered.
<ruby>
-config.active_record.observers = ["MailObserver"]
+config.action_mailer.observers = ["MailObserver"]
</ruby>
* +config.action_mailer.interceptors+ registers interceptors which will be called before mail is sent.
<ruby>
-config.active_record.interceptors = ["MailInterceptor"]
+config.action_mailer.interceptors = ["MailInterceptor"]
</ruby>
h4. Configuring Active Resource
@@ -478,13 +493,13 @@ Serves as a placeholder so that +:load_environment_config+ can be defined to run
*+set_clear_dependencies_hook+* Provides a hook for +active_record.set_dispatch_hooks+ to use, which will run before this initializer. This initializer -- which runs only if +cache_classes+ is set to +false+ -- uses +ActionDispatch::Callbacks.after+ to remove the constants which have been referenced during the request from the object space so that they will be reloaded during the following request.
-*+initialize_dependency_mechanism+* If +config.cache_classes+ is set to +true+, configures +ActiveSupport::Dependencies.mechanism+ to +require+ dependencies rather than +load+ them.
+*+initialize_dependency_mechanism+* If +config.cache_classes+ is true, configures +ActiveSupport::Dependencies.mechanism+ to +require+ dependencies rather than +load+ them.
*+bootstrap_hook+* Runs all configured +before_initialize+ blocks.
*+i18n.callbacks+* In the development environment, sets up a +to_prepare+ callback which will call +I18n.reload!+ if any of the locales have changed since the last request. In production mode this callback will only run on the first request.
-*+active_support.initialize_whiny_nils+* Requires +active_support/whiny_nil+ if +config.whiny_nils+ is set to +true+. This file will output errors such as:
+*+active_support.initialize_whiny_nils+* Requires +active_support/whiny_nil+ if +config.whiny_nils+ is true. This file will output errors such as:
<plain>
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
@@ -568,13 +583,13 @@ The error occurred while evaluating nil.each
*+build_middleware_stack+* Builds the middleware stack for the application, returning an object which has a +call+ method which takes a Rack environment object for the request.
-*+eager_load!+* If +config.cache_classes+ is +true+, runs the +config.before_eager_load+ hooks and then calls +eager_load!+ which will load all the Ruby files from +config.eager_load_paths+.
+*+eager_load!+* If +config.cache_classes+ is true, runs the +config.before_eager_load+ hooks and then calls +eager_load!+ which will load all the Ruby files from +config.eager_load_paths+.
*+finisher_hook+* Provides a hook for after the initialization of process of the application is complete, as well as running all the +config.after_initialize+ blocks for the application, railties and engines.
*+set_routes_reloader+* Configures Action Dispatch to reload the routes file using +ActionDispatch::Callbacks.to_prepare+.
-*+disable_dependency_loading+* Disables the automatic dependency loading if the +config.cache_classes+ is set to +true+ and +config.dependency_loading+ is set to +false+.
+*+disable_dependency_loading+* Disables the automatic dependency loading if the +config.cache_classes+ is set to true and +config.dependency_loading+ is set to false.
h3. Changelog
diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile
index 2ce8ddc702..e6ec061c9a 100644
--- a/railties/guides/source/contributing_to_ruby_on_rails.textile
+++ b/railties/guides/source/contributing_to_ruby_on_rails.textile
@@ -350,7 +350,7 @@ Navigate to the Rails "GitHub repository":https://github.com/rails/rails and pre
Add the new remote to your local repository on your local machine:
<shell>
-$ git remote add mine https://<your user name>@github.com/<your user name>/rails.git
+$ git remote add mine git@github.com:<your user name>/rails.git
</shell>
Push to your remote:
@@ -361,7 +361,7 @@ $ git push mine my_new_branch
h4. Issue a Pull Request
-Navigate to the Rails repository you just pushed to (e.g. https://github.com/<your user name>/rails) and press "Pull Request" in the upper right hand corner.
+Navigate to the Rails repository you just pushed to (e.g. https://github.com/your-user-name/rails) and press "Pull Request" in the upper right hand corner.
Write your branch name in branch field (is filled with master by default) and press "Update Commit Range"
diff --git a/railties/guides/source/debugging_rails_applications.textile b/railties/guides/source/debugging_rails_applications.textile
index 6f028805d6..f5bee52b5a 100644
--- a/railties/guides/source/debugging_rails_applications.textile
+++ b/railties/guides/source/debugging_rails_applications.textile
@@ -127,7 +127,7 @@ When something is logged it's printed into the corresponding log if the log leve
The available log levels are: +:debug+, +:info+, +:warn+, +:error+, and +:fatal+, corresponding to the log level numbers from 0 up to 4 respectively. To change the default log level, use
<ruby>
-config.log_level = Logger::WARN # In any environment initializer, or
+config.log_level = :warn # In any environment initializer, or
Rails.logger.level = 0 # at any time
</ruby>
@@ -480,11 +480,7 @@ class Author < ActiveRecord::Base
def find_recent_comments(limit = 10)
debugger
- @recent_comments ||= comments.find(
- :all,
- :conditions => ["created_at > ?", 1.week.ago],
- :limit => limit
- )
+ @recent_comments ||= comments.where("created_at > ?", 1.week.ago).limit(limit)
end
end
</ruby>
@@ -493,7 +489,7 @@ TIP: You can use ruby-debug while using +rails console+. Just remember to +requi
<shell>
$ rails console
-Loading development environment (Rails 2.1.0)
+Loading development environment (Rails 3.1.0)
>> require "ruby-debug"
=> []
>> author = Author.first
@@ -507,15 +503,15 @@ With the code stopped, take a look around:
<shell>
(rdb:1) list
-[6, 15] in /PathTo/project/app/models/author.rb
+[2, 9] in /PathTo/project/app/models/author.rb
+ 2 has_one :editorial
+ 3 has_many :comments
+ 4
+ 5 def find_recent_comments(limit = 10)
6 debugger
- 7 @recent_comments ||= comments.find(
- 8 :all,
- 9 :conditions => ["created_at > ?", 1.week.ago],
- 10 :limit => limit
-=> 11 )
- 12 end
- 13 end
+=> 7 @recent_comments ||= comments.where("created_at > ?", 1.week.ago).limit(limit)
+ 8 end
+ 9 end
</shell>
You are at the end of the line, but... was this line executed? You can inspect the instance variables.
diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile
index c7e45c0a23..9051ede9dd 100644
--- a/railties/guides/source/form_helpers.textile
+++ b/railties/guides/source/form_helpers.textile
@@ -589,7 +589,7 @@ def upload
end
</ruby>
-Once a file has been uploaded, there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. The intricacies of this are beyond the scope of this guide, but there are several plugins designed to assist with these. Two of the better known ones are "Attachment-Fu":https://github.com/technoweenie/attachment_fu and "Paperclip":http://www.thoughtbot.com/projects/paperclip.
+Once a file has been uploaded, there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. The intricacies of this are beyond the scope of this guide, but there are several libraries designed to assist with these. Two of the better known ones are "CarrierWave":https://github.com/jnicklas/carrierwave and "Paperclip":http://www.thoughtbot.com/projects/paperclip.
NOTE: If the user has not selected a file the corresponding parameter will be an empty string.
@@ -777,7 +777,7 @@ If you need to post some data to an external resource it is still great to build
Sometimes when you submit data to an external resource, like payment gateway, fields you can use in your form are limited by an external API. So you may want not to generate an +authenticity_token+ hidden field at all. For doing this just pass +false+ to the +:authenticity_token+ option:
<erb>
-<%= form_tag 'http://farfar.away/form', :authenticity_token => 'external_token') do %>
+<%= form_tag 'http://farfar.away/form', :authenticity_token => false) do %>
Form contents
<% end %>
</erb>
diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile
index 670979c3c2..6aca5d3420 100644
--- a/railties/guides/source/getting_started.textile
+++ b/railties/guides/source/getting_started.textile
@@ -5,7 +5,7 @@ This guide covers getting up and running with Ruby on Rails. After reading it, y
* Installing Rails, creating a new Rails application, and connecting your application to a database
* The general layout of a Rails application
* The basic principles of MVC (Model, View Controller) and RESTful design
-* How to quickly generate the starting pieces of a Rails application.
+* How to quickly generate the starting pieces of a Rails application
endprologue.
@@ -177,14 +177,14 @@ In any case, Rails will create a folder in your working directory called <tt>blo
|Gemfile|This file allows you to specify what gem dependencies are needed for your Rails application.|
|README|This is a brief instruction manual for your application. Use it to tell others what your application does, how to set it up, and so on.|
|Rakefile|This file contains batch jobs that can be run from the terminal.|
-|app/|Contains the controllers, models, and views for your application. You'll focus on this folder for the remainder of this guide.|
+|app/|Contains the controllers, models, views and assets for your application. You'll focus on this folder for the remainder of this guide.|
|config/|Configure your application's runtime rules, routes, database, and more.|
|config.ru|Rack configuration for Rack based servers used to start the application.|
|db/|Shows your current database schema, as well as the database migrations. You'll learn about migrations shortly.|
|doc/|In-depth documentation for your application.|
|lib/|Extended modules for your application (not covered in this guide).|
|log/|Application log files.|
-|public/|The only folder seen to the world as-is. This is where your images, JavaScript files, stylesheets (CSS), and other static files go.|
+|public/|The only folder seen to the world as-is. Contains the static files and compiled assets.|
|script/|Contains the rails script that starts your app and can contain other scripts you use to deploy or run your application.|
|test/|Unit tests, fixtures, and other test apparatus. These are covered in "Testing Rails Applications":testing.html|
|tmp/|Temporary files|
@@ -205,8 +205,8 @@ h4. Configuring a Database
Just about every Rails application will interact with a database. The database to use is specified in a configuration file, +config/database.yml+.
If you open this file in a new Rails application, you'll see a default database configuration using SQLite3. The file contains sections for three different environments in which Rails can run by default:
-* The +development+ environment is used on your development computer as you interact manually with the application
-* The +test+ environment is used to run automated tests
+* The +development+ environment is used on your development computer as you interact manually with the application.
+* The +test+ environment is used to run automated tests.
* The +production+ environment is used when you deploy your application for the world to use.
h5. Configuring an SQLite3 Database
@@ -244,7 +244,7 @@ If your development computer's MySQL installation includes a root user with an e
h5. Configuring a PostgreSQL Database
-Finally if you choose to use PostgreSQL, your +config/database.yml+ will be customized to use PostgreSQL databases:
+If you choose to use PostgreSQL, your +config/database.yml+ will be customized to use PostgreSQL databases:
<yaml>
development:
@@ -256,6 +256,41 @@ development:
password:
</yaml>
+h5. Configuring an SQLite3 Database for JRuby Platform
+
+If you choose to use SQLite3 and using JRuby, your +config/database.yml+ will look a little different. Here's the development section:
+
+<yaml>
+development:
+ adapter: jdbcsqlite3
+ database: db/development.sqlite3
+</yaml>
+
+h5. Configuring a MySQL Database for JRuby Platform
+
+If you choose to use MySQL and using JRuby, your +config/database.yml+ will look a little different. Here's the development section:
+
+<yaml>
+development:
+ adapter: jdbcmysql
+ database: blog_development
+ username: root
+ password:
+</yaml>
+
+h5. Configuring a PostgreSQL Database for JRuby Platform
+
+Finally if you choose to use PostgreSQL and using JRuby, your +config/database.yml+ will look a little different. Here's the development section:
+
+<yaml>
+development:
+ adapter: jdbcpostgresql
+ encoding: unicode
+ database: blog_development
+ username: blog
+ password:
+</yaml>
+
Change the username and password in the +development+ section as appropriate.
TIP: You don't have to update the database configurations manually. If you had a look at the options of application generator, you have seen that one of them is named <tt>--database</tt>. It lets you choose an adapter for couple of most used relational databases. You can even run the generator repeatedly: <tt>cd .. && rails new blog --database=mysql</tt>. When you confirm the overwriting of the +config/database.yml+ file, your application will be configured for MySQL instead of SQLite.
@@ -290,7 +325,7 @@ This will fire up an instance of the WEBrick web server by default (Rails can al
TIP: To stop the web server, hit Ctrl+C in the terminal window where it's running. In development mode, Rails does not generally require you to stop the server; changes you make in files will be automatically picked up by the server.
-The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. You can also click on the _About your application’s environment_ link to see a summary of your Application's environment.
+The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. You can also click on the _About your application’s environment_ link to see a summary of your application's environment.
h4. Say "Hello", Rails
@@ -364,11 +399,11 @@ The scaffold generator will build 15 files in your application, along with some
|app/views/posts/new.html.erb |A view to create a new post|
|app/views/posts/_form.html.erb |A partial to control the overall look and feel of the form used in edit and new views|
|app/helpers/posts_helper.rb |Helper functions to be used from the post views|
+|app/assets/stylesheets/scaffold.css.scss |Cascading style sheet to make the scaffolded views look better|
|test/unit/post_test.rb |Unit testing harness for the posts model|
|test/functional/posts_controller_test.rb |Functional testing harness for the posts controller|
|test/unit/helpers/posts_helper_test.rb |Unit testing harness for the posts helper|
|config/routes.rb |Edited to include routing information for posts|
-|app/assets/stylesheets/scaffold.css.scss |Cascading style sheet to make the scaffolded views look better|
h4. Running a Migration
@@ -413,10 +448,10 @@ h4. Adding a Link
To hook the posts up to the home page you've already created, you can add a link to the home page. Open +app/views/home/index.html.erb+ and modify it as follows:
-<code lang="ruby">
+<ruby>
<h1>Hello, Rails!</h1>
<%= link_to "My Blog", posts_path %>
-</code>
+</ruby>
The +link_to+ method is one of Rails' built-in view helpers. It creates a hyperlink based on text to display and where to go - in this case, to the path for posts.
diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile
index 1d5b0c0c11..340699419b 100644
--- a/railties/guides/source/initialization.textile
+++ b/railties/guides/source/initialization.textile
@@ -661,9 +661,9 @@ require 'active_support/inflections'
require 'active_support/core_ext/string/inflections'
</ruby>
-The +active_support/inflector/methods+ file has already been required by +active_support/autoload+ and so won't be loaded again here.
+The +active_support/inflector/methods+ file has already been required by +active_support/autoload+ and so won't be loaded again here. The +activesupport/lib/active_support/inflector/inflections.rb+ is required by +active_support/inflector/methods+.
-h4. +activesupport/lib/active_support/inflector/inflections.rb+
+h4. +active_support/inflections+
This file references the +ActiveSupport::Inflector+ constant which isn't loaded by this point. But there were autoloads set up in +activesupport/lib/active_support.rb+ which will load the file which loads this constant and so then it will be defined. Then this file defines pluralization and singularization rules for words in Rails. This is how Rails knows how to pluralize "tomato" to "tomatoes".
diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile
index f17f686d47..dbbf8f3b51 100644
--- a/railties/guides/source/migrations.textile
+++ b/railties/guides/source/migrations.textile
@@ -344,7 +344,7 @@ The +change+ method removes the need to write both +up+ and +down+ methods in th
* +add_column+
* +add_index+
-* +add_timestamp+
+* +add_timestamps+
* +create_table+
* +remove_timestamps+
* +rename_column+
diff --git a/railties/guides/source/nested_model_forms.textile b/railties/guides/source/nested_model_forms.textile
index 55694c0eb4..4b1fd2e0ac 100644
--- a/railties/guides/source/nested_model_forms.textile
+++ b/railties/guides/source/nested_model_forms.textile
@@ -90,7 +90,7 @@ h3. Views
h4. Controller code
-A nested model form will _only_ be build if the associated object(s) exist. This means that for a new model instance you would probably want to build the associated object(s) first.
+A nested model form will _only_ be built if the associated object(s) exist. This means that for a new model instance you would probably want to build the associated object(s) first.
Consider the following typical RESTful controller which will prepare a new Person instance and its +address+ and +projects+ associations before rendering the +new+ template:
@@ -144,7 +144,7 @@ Now add a nested form for the +address+ association:
<%= f.text_field :name %>
<%= f.fields_for :address do |af| %>
- <%= f.text_field :street %>
+ <%= af.text_field :street %>
<% end %>
<% end %>
</erb>
@@ -159,7 +159,7 @@ This generates:
</form>
</html>
-Notice that +fields_for+ recognized the +address+ as an association for which a nested model form should be build by the way it has namespaced the +name+ attribute.
+Notice that +fields_for+ recognized the +address+ as an association for which a nested model form should be built by the way it has namespaced the +name+ attribute.
When this form is posted the Rails parameter parser will construct a hash like the following:
@@ -185,7 +185,7 @@ The form code for an association collection is pretty similar to that of a singl
<%= f.text_field :name %>
<%= f.fields_for :projects do |pf| %>
- <%= f.text_field :name %>
+ <%= pf.text_field :name %>
<% end %>
<% end %>
</erb>
@@ -201,7 +201,7 @@ Which generates:
</form>
</html>
-As you can see it has generated 2 +project name+ inputs, one for each new +project+ that’s build in the controllers +new+ action. Only this time the +name+ attribute of the input contains a digit as an extra namespace. This will be parsed by the Rails parameter parser as:
+As you can see it has generated 2 +project name+ inputs, one for each new +project+ that was built in the controller's +new+ action. Only this time the +name+ attribute of the input contains a digit as an extra namespace. This will be parsed by the Rails parameter parser as:
<ruby>
{
@@ -215,7 +215,7 @@ As you can see it has generated 2 +project name+ inputs, one for each new +proje
}
</ruby>
-You can basically see the +projects_attributes+ hash as an array of attribute hashes. One for each model instance.
+You can basically see the +projects_attributes+ hash as an array of attribute hashes, one for each model instance.
NOTE: The reason that +fields_for+ constructed a form which would result in a hash instead of an array is that it won't work for any forms nested deeper than one level deep.
diff --git a/railties/guides/source/performance_testing.textile b/railties/guides/source/performance_testing.textile
index 83db7eee59..dbe6f97f5c 100644
--- a/railties/guides/source/performance_testing.textile
+++ b/railties/guides/source/performance_testing.textile
@@ -66,7 +66,7 @@ resources :posts
# home_controller.rb
class HomeController < ApplicationController
def dashboard
- @users = User.last_ten(:include => :avatars)
+ @users = User.last_ten.includes(:avatars)
@posts = Post.all_today
end
end
@@ -151,7 +151,7 @@ Performance tests can be run in two modes: Benchmarking and Profiling.
h5. Benchmarking
-Benchmarking makes it easy to quickly gather a few metrics about each test tun. By default, each test case is run +4 times+ in benchmarking mode.
+Benchmarking makes it easy to quickly gather a few metrics about each test tun. By default, each test case is run *4 times* in benchmarking mode.
To run performance tests in benchmarking mode:
@@ -161,7 +161,7 @@ $ rake test:benchmark
h5. Profiling
-Profiling allows you to make an in-depth analysis of each of your tests by using an external profiler. Depending on your Ruby interpreter, this profiler can be native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each test case is run +1 time+ in profiling mode.
+Profiling allows you to make an in-depth analysis of each of your tests by using an external profiler. Depending on your Ruby interpreter, this profiler can be native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each test case is run *once* in profiling mode.
To run performance tests in profiling mode:
@@ -481,7 +481,7 @@ h4. +profiler+
Usage:
<shell>
-Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS]
+Usage: rails profiler 'Ruby.code' 'Ruby.more_code' ... [OPTS]
-r, --runs N Number of runs.
Default: 1
-o, --output PATH Directory to use when writing the results.
@@ -573,7 +573,7 @@ h3. Useful Links
h4. Rails Plugins and Gems
* "Rails Analyzer":http://rails-analyzer.rubyforge.org
-* "Palmist":http://www.flyingmachinestudios.com/projects/
+* "Palmist":http://www.flyingmachinestudios.com/programming/announcing-palmist
* "Rails Footnotes":https://github.com/josevalim/rails-footnotes/tree/master
* "Query Reviewer":https://github.com/dsboulder/query_reviewer/tree/master
diff --git a/railties/guides/source/plugins.textile b/railties/guides/source/plugins.textile
index 2eb71e49c4..79bbe495bd 100644
--- a/railties/guides/source/plugins.textile
+++ b/railties/guides/source/plugins.textile
@@ -37,7 +37,7 @@ Use the +rails generate plugin+ command in your Rails root directory
directory. See usage and options by asking for help:
<shell>
-$ rails generate plugin new --help
+$ rails generate plugin --help
</shell>
h4. Or generate a gemified plugin.
diff --git a/railties/guides/source/rails_application_templates.textile b/railties/guides/source/rails_application_templates.textile
index 388d8eea3e..3db47a70e8 100644
--- a/railties/guides/source/rails_application_templates.textile
+++ b/railties/guides/source/rails_application_templates.textile
@@ -1,6 +1,6 @@
h2. Rails Application Templates
-Application templates are simple ruby files containing DSL for adding plugins/gems/initializers etc. to your freshly created Rails project or an existing Rails project.
+Application templates are simple Ruby files containing DSL for adding plugins/gems/initializers etc. to your freshly created Rails project or an existing Rails project.
By referring to this guide, you will be able to:
@@ -58,14 +58,12 @@ gem "bj"
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:
+Please note that this will NOT install the gems for you and you will have to run +bundle install+ to do that.
<ruby>
-rake "gems:install"
+bundle install
</ruby>
-And let Rails take care of installing the required gems if they’re not already installed.
-
h4. add_source(source, options = {})
Adds the given source to the generated application's +Gemfile+.
@@ -229,7 +227,7 @@ rake("rails:freeze:gems") if yes?("Freeze rails gems ?")
no?(question) acts just the opposite.
</ruby>
-h4. git(:must => "-a love")
+h4. git(:command)
Rails templates let you run any git command:
diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile
index 412ded1d0b..908f3f125a 100644
--- a/railties/guides/source/security.textile
+++ b/railties/guides/source/security.textile
@@ -649,7 +649,7 @@ h5(#sql-injection-introduction). Introduction
SQL injection attacks aim at influencing database queries by manipulating web application parameters. A popular goal of SQL injection attacks is to bypass authorization. Another goal is to carry out data manipulation or reading arbitrary data. Here is an example of how not to use user input data in a query:
<ruby>
-Project.all(:conditions => "name = '#{params[:name]}'")
+Project.where("name = '#{params[:name]}'")
</ruby>
This could be in a search action and the user may enter a project's name that he wants to find. If a malicious user enters ' OR 1 --, the resulting SQL query will be:
@@ -681,7 +681,7 @@ h5. Unauthorized Reading
The UNION statement connects two SQL queries and returns the data in one set. An attacker can use it to read arbitrary data from the database. Let's take the example from above:
<ruby>
-Project.all(:conditions => "name = '#{params[:name]}'")
+Project.where("name = '#{params[:name]}'")
</ruby>
And now let's inject another query using the UNION statement:
@@ -703,18 +703,18 @@ Also, the second query renames some columns with the AS statement so that the we
h5(#sql-injection-countermeasures). Countermeasures
-Ruby on Rails has a built-in filter for special SQL characters, which will escape ' , " , NULL character and line breaks. <em class="highlight">Using +Model.find(id)+ or +Model.find_by_some thing(something)+ automatically applies this countermeasure</em>. But in SQL fragments, especially <em class="highlight">in conditions fragments (+:conditions => "..."+), the +connection.execute()+ or +Model.find_by_sql()+ methods, it has to be applied manually</em>.
+Ruby on Rails has a built-in filter for special SQL characters, which will escape ' , " , NULL character and line breaks. <em class="highlight">Using +Model.find(id)+ or +Model.find_by_some thing(something)+ automatically applies this countermeasure</em>. But in SQL fragments, especially <em class="highlight">in conditions fragments (+where("...")+), the +connection.execute()+ or +Model.find_by_sql()+ methods, it has to be applied manually</em>.
Instead of passing a string to the conditions option, you can pass an array to sanitize tainted strings like this:
<ruby>
-Model.first(:conditions => ["login = ? AND password = ?", entered_user_name, entered_password])
+Model.where("login = ? AND password = ?", entered_user_name, entered_password).first
</ruby>
As you can see, the first part of the array is an SQL fragment with question marks. The sanitized versions of the variables in the second part of the array replace the question marks. Or you can pass a hash for the same result:
<ruby>
-Model.first(:conditions => {:login => entered_user_name, :password => entered_password})
+Model.where(:login => entered_user_name, :password => entered_password).first
</ruby>
The array or hash form is only available in model instances. You can try +sanitize_sql()+ elsewhere. _(highlight)Make it a habit to think about the security consequences when using an external string in SQL_.
diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile
index db9c7545c8..cc55d1f756 100644
--- a/railties/guides/source/testing.textile
+++ b/railties/guides/source/testing.textile
@@ -944,7 +944,7 @@ The built-in +test/unit+ based testing is not the only way to test Rails applica
* "Factory Girl":https://github.com/thoughtbot/factory_girl/tree/master, a replacement for fixtures.
* "Machinist":https://github.com/notahat/machinist/tree/master, another replacement for fixtures.
* "Shoulda":http://www.thoughtbot.com/projects/shoulda, an extension to +test/unit+ with additional helpers, macros, and assertions.
-* "RSpec":http://rspec.info/, a behavior-driven development framework
+* "RSpec":http://relishapp.com/rspec, a behavior-driven development framework
h3. Changelog
diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb
index cca0891835..603ede3d1e 100644
--- a/railties/lib/rails.rb
+++ b/railties/lib/rails.rb
@@ -4,6 +4,7 @@ require 'pathname'
require 'active_support'
require 'active_support/core_ext/kernel/reporting'
+require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/logger'
require 'rails/application'
@@ -87,6 +88,31 @@ module Rails
RAILS_CACHE
end
+ # Returns all rails groups for loading based on:
+ #
+ # * The Rails environment;
+ # * The environment variable RAILS_GROUPS;
+ # * The optional envs given as argument and the hash with group dependencies;
+ #
+ # == Examples
+ #
+ # groups :assets => [:development, :test]
+ #
+ # # Returns
+ # # => [:default, :development, :assets] for Rails.env == "development"
+ # # => [:default, :production] for Rails.env == "production"
+ #
+ def groups(*groups)
+ hash = groups.extract_options!
+ env = Rails.env
+ groups.unshift(:default, env)
+ groups.concat ENV["RAILS_GROUPS"].to_s.split(",")
+ groups.concat hash.map { |k,v| k if v.map(&:to_s).include?(env) }
+ groups.compact!
+ groups.uniq!
+ groups
+ end
+
def version
VERSION::STRING
end
diff --git a/railties/lib/rails/all.rb b/railties/lib/rails/all.rb
index 82775b7e3b..01ceb80972 100644
--- a/railties/lib/rails/all.rb
+++ b/railties/lib/rails/all.rb
@@ -6,6 +6,7 @@ require "rails"
action_mailer
active_resource
rails/test_unit
+ sprockets
).each do |framework|
begin
require "#{framework}/railtie"
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index a2b2af98a6..559739b2ec 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -78,10 +78,6 @@ module Rails
require environment if environment
end
- def eager_load! #:nodoc:
- railties.all(&:eager_load!)
- super
- end
def reload_routes!
routes_reloader.reload!
@@ -100,18 +96,25 @@ module Rails
def load_tasks(app=self)
initialize_tasks
- railties.all { |r| r.load_tasks(app) }
super
self
end
def load_console(app=self)
initialize_console
- railties.all { |r| r.load_console(app) }
super
self
end
+ # Rails.application.env_config stores some of the Rails initial environment parameters.
+ # Currently stores:
+ #
+ # * action_dispatch.parameter_filter" => config.filter_parameters,
+ # * action_dispatch.secret_token" => config.secret_token,
+ # * action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions
+ #
+ # These parameters will be used by middlewares and engines to configure themselves.
+ #
def env_config
@env_config ||= super.merge({
"action_dispatch.parameter_filter" => config.filter_parameters,
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 3b74de690a..1a29483a73 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -34,7 +34,7 @@ module Rails
@assets = ActiveSupport::OrderedOptions.new
@assets.enabled = false
@assets.paths = []
- @assets.precompile = [ /\w+\.(?!js|css).+/, "application.js", "application.css" ]
+ @assets.precompile = [ /\w+\.(?!js|css).+/, /application.(css|js)$/ ]
@assets.prefix = "/assets"
@assets.js_compressor = nil
diff --git a/railties/lib/rails/application/railties.rb b/railties/lib/rails/application/railties.rb
index 4fc5e92837..8f3a3e8bbb 100644
--- a/railties/lib/rails/application/railties.rb
+++ b/railties/lib/rails/application/railties.rb
@@ -4,7 +4,7 @@ module Rails
class Application < Engine
class Railties < Rails::Engine::Railties
def all(&block)
- @all ||= railties + engines + super
+ @all ||= railties + engines + plugins
@all.each(&block) if block
@all
end
diff --git a/railties/lib/rails/commands/plugin.rb b/railties/lib/rails/commands/plugin.rb
index 048af7cbef..4df849447d 100644
--- a/railties/lib/rails/commands/plugin.rb
+++ b/railties/lib/rails/commands/plugin.rb
@@ -313,11 +313,11 @@ module Commands
o.separator ""
o.separator "EXAMPLES"
o.separator " Install a plugin from a subversion URL:"
- o.separator " #{@script_name} plugin install http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder\n"
+ o.separator " #{@script_name} plugin install http://example.com/my_svn_plugin\n"
o.separator " Install a plugin from a git URL:"
o.separator " #{@script_name} plugin install git://github.com/SomeGuy/my_awesome_plugin.git\n"
o.separator " Install a plugin and add a svn:externals entry to vendor/plugins"
- o.separator " #{@script_name} plugin install -x continuous_builder\n"
+ o.separator " #{@script_name} plugin install -x my_svn_plugin\n"
end
end
diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb
index f8b00e7249..e8cc5d9e3b 100644
--- a/railties/lib/rails/commands/runner.rb
+++ b/railties/lib/rails/commands/runner.rb
@@ -4,6 +4,10 @@ require 'rbconfig'
options = { :environment => (ENV['RAILS_ENV'] || "development").dup }
code_or_file = nil
+if ARGV.first.nil?
+ ARGV.push "-h"
+end
+
ARGV.clone.options do |opts|
script_name = File.basename($0)
opts.banner = "Usage: runner [options] ('Some.ruby(code)' or a filename)"
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index b358de89d0..eb6fcd5dd7 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -395,12 +395,20 @@ module Rails
delegate :middleware, :root, :paths, :to => :config
delegate :engine_name, :isolated?, :to => "self.class"
- def load_tasks(*)
+ def load_tasks(app=self)
+ railties.all { |r| r.load_tasks(app) }
super
paths["lib/tasks"].existent.sort.each { |ext| load(ext) }
end
-
+
+ def load_console(app=self)
+ railties.all { |r| r.load_console(app) }
+ super
+ end
+
def eager_load!
+ railties.all(&:eager_load!)
+
config.eager_load_paths.each do |load_path|
matcher = /\A#{Regexp.escape(load_path)}\/(.*)\.rb\Z/
Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
@@ -530,15 +538,9 @@ module Rails
end
initializer :append_assets_path do |app|
- if app.config.assets.respond_to?(:prepend_path)
- app.config.assets.prepend_path(*paths["vendor/assets"].existent)
- app.config.assets.prepend_path(*paths["lib/assets"].existent)
- app.config.assets.prepend_path(*paths["app/assets"].existent)
- else
- app.config.assets.paths.unshift(*paths["vendor/assets"].existent)
- app.config.assets.paths.unshift(*paths["lib/assets"].existent)
- app.config.assets.paths.unshift(*paths["app/assets"].existent)
- end
+ app.config.assets.paths.unshift(*paths["vendor/assets"].existent)
+ app.config.assets.paths.unshift(*paths["lib/assets"].existent)
+ app.config.assets.paths.unshift(*paths["app/assets"].existent)
end
initializer :prepend_helpers_path do |app|
@@ -584,7 +586,7 @@ module Rails
end
def has_migrations?
- paths["db/migrate"].first.present?
+ paths["db/migrate"].existent.any?
end
def find_root_with_flag(flag, default=nil)
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 355b05ce0b..fdafc91fcb 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -53,7 +53,7 @@ module Rails
:helper => true,
:integration_tool => nil,
:javascripts => true,
- :javascript_engine => nil,
+ :javascript_engine => :js,
:orm => false,
:performance_tool => nil,
:resource_controller => :controller,
@@ -299,9 +299,6 @@ module Rails
return
rescue LoadError => e
raise unless e.message =~ /#{Regexp.escape(path)}$/
- rescue NameError => e
- raise unless e.message =~ /Rails::Generator([\s(::)]|$)/
- warn "[WARNING] Could not load generator #{path.inspect} because it's a Rails 2.x generator, which is not supported anymore. Error: #{e.message}.\n#{e.backtrace.join("\n")}"
rescue Exception => e
warn "[WARNING] Could not load generator #{path.inspect}. Error: #{e.message}.\n#{e.backtrace.join("\n")}"
end
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index d31a3262e3..433a56dc57 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -114,11 +114,11 @@ module Rails
# git :add => "this.file that.rb"
# git :add => "onefile.rb", :rm => "badfile.cxx"
#
- def git(command={})
- if command.is_a?(Symbol)
- run "git #{command}"
+ def git(commands={})
+ if commands.is_a?(Symbol)
+ run "git #{commands}"
else
- command.each do |command, options|
+ commands.each do |command, options|
run "git #{command} #{options}"
end
end
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 7972c72c1e..bbdd000ad9 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -10,7 +10,7 @@ module Rails
module Generators
class AppBase < Base
DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
- JDBC_DATABASES = %w( jdbcmysql jdbcsqlite3 jdbcpostgresql )
+ JDBC_DATABASES = %w( jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc )
DATABASES.concat(JDBC_DATABASES)
attr_accessor :rails_template
@@ -37,6 +37,9 @@ module Rails
class_option :skip_active_record, :type => :boolean, :aliases => "-O", :default => false,
:desc => "Skip Active Record files"
+ class_option :skip_sprockets, :type => :boolean, :aliases => "-S", :default => false,
+ :desc => "Skip Sprockets files"
+
class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
:desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
@@ -64,8 +67,8 @@ module Rails
def initialize(*args)
@original_wd = Dir.pwd
-
super
+ convert_database_option_for_jruby
end
protected
@@ -124,7 +127,7 @@ module Rails
end
def include_all_railties?
- !options[:skip_active_record] && !options[:skip_test_unit]
+ !options[:skip_active_record] && !options[:skip_test_unit] && !options[:skip_sprockets]
end
def comment_if(value)
@@ -157,14 +160,26 @@ module Rails
when "postgresql" then "pg"
when "frontbase" then "ruby-frontbase"
when "mysql" then "mysql2"
- when "jdbcmysql" then "activerecord-jdbcmysql-adapter"
- when "jdbcsqlite3" then "activerecord-jdbcsqlite3-adapter"
- when "jdbcpostgresql" then "activerecord-jdbcpostgresql-adapter"
+ when "jdbcmysql" then "activerecord-jdbcmysql-adapter"
+ when "jdbcsqlite3" then "activerecord-jdbcsqlite3-adapter"
+ when "jdbcpostgresql" then "activerecord-jdbcpostgresql-adapter"
+ when "jdbc" then "activerecord-jdbc-adapter"
else options[:database]
end
end
- def gem_for_ruby_debugger
+ def convert_database_option_for_jruby
+ if defined?(JRUBY_VERSION)
+ case options[:database]
+ when "oracle" then options[:database].replace "jdbc"
+ when "postgresql" then options[:database].replace "jdbcpostgresql"
+ when "mysql" then options[:database].replace "jdbcmysql"
+ when "sqlite3" then options[:database].replace "jdbcsqlite3"
+ end
+ end
+ end
+
+ def ruby_debugger_gemfile_entry
if RUBY_VERSION < "1.9"
"gem 'ruby-debug'"
else
@@ -172,7 +187,7 @@ module Rails
end
end
- def gem_for_turn
+ def turn_gemfile_entry
unless RUBY_VERSION < "1.9.2" || options[:skip_test_unit]
<<-GEMFILE.strip_heredoc
group :test do
@@ -183,18 +198,34 @@ module Rails
end
end
- def gem_for_javascript
+ def assets_gemfile_entry
+ <<-GEMFILE.strip_heredoc
+ group :assets do
+ gem 'sass-rails', :git => 'git://github.com/rails/sass-rails'
+ gem 'coffee-rails', :git => 'git://github.com/rails/coffee-rails'
+ gem 'uglifier'
+ end
+ GEMFILE
+ end
+
+ def javascript_gemfile_entry
"gem '#{options[:javascript]}-rails'" unless options[:skip_javascript]
end
def bundle_command(command)
- require 'bundler'
- require 'bundler/cli'
-
say_status :run, "bundle #{command}"
- Bundler::CLI.new.send(command)
- rescue
- say_status :failure, "bundler raised an exception, are you offline?", :red
+
+ # We are going to shell out rather than invoking Bundler::CLI.new(command)
+ # because `rails new` loads the Thor gem and on the other hand bundler uses
+ # its own vendored Thor, which could be a different version. Running both
+ # things in the same process is a recipe for a night with paracetamol.
+ #
+ # We use backticks and #print here instead of vanilla #system because it
+ # is easier to silence stdout in the existing test suite this way. The
+ # end-user gets the bundler commands called anyway, so no big deal.
+ #
+ # Thanks to James Tucker for the Gem tricks involved in this call.
+ print `"#{Gem.ruby}" -rubygems "#{Gem.bin_path('bundler', 'bundle')}" #{command}`
end
def run_bundle
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb
index 1f6a7a2f59..b9dc31457a 100644
--- a/railties/lib/rails/generators/base.rb
+++ b/railties/lib/rails/generators/base.rb
@@ -259,9 +259,9 @@ module Rails
extra << false unless Object.method(:const_defined?).arity == 1
# Extract the last Module in the nesting
- last = nesting.inject(Object) do |last, nest|
- break unless last.const_defined?(nest, *extra)
- last.const_get(nest)
+ last = nesting.inject(Object) do |last_module, nest|
+ break unless last_module.const_defined?(nest, *extra)
+ last_module.const_get(nest)
end
if last && last.const_defined?(last_name.camelize, *extra)
diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb
index 9450894b05..f9f89c9f1d 100644
--- a/railties/lib/rails/generators/generated_attribute.rb
+++ b/railties/lib/rails/generators/generated_attribute.rb
@@ -7,7 +7,7 @@ module Rails
attr_accessor :name, :type
def initialize(name, type)
- raise Thor::Error, "Missing type for attribute '#{name}'.\nExample: '#{name}:string' where string is the type." if type.blank?
+ type = :string if type.blank?
@name, @type = name, type.to_sym
end
diff --git a/railties/lib/rails/generators/js/assets/assets_generator.rb b/railties/lib/rails/generators/js/assets/assets_generator.rb
new file mode 100644
index 0000000000..d134a9e392
--- /dev/null
+++ b/railties/lib/rails/generators/js/assets/assets_generator.rb
@@ -0,0 +1,13 @@
+require "rails/generators/named_base"
+
+module Js
+ module Generators
+ class AssetsGenerator < Rails::Generators::NamedBase
+ source_root File.expand_path("../templates", __FILE__)
+
+ def copy_javascript
+ copy_file "javascript.js", File.join('app/assets/javascripts', class_path, "#{file_name}.js")
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/js/assets/templates/javascript.js b/railties/lib/rails/generators/js/assets/templates/javascript.js
new file mode 100644
index 0000000000..dee720facd
--- /dev/null
+++ b/railties/lib/rails/generators/js/assets/templates/javascript.js
@@ -0,0 +1,2 @@
+// Place all the behaviors and hooks related to the matching controller here.
+// All this logic will automatically be available in application.js.
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 242677cc65..6af9d299aa 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -88,6 +88,7 @@ module Rails
def lib
empty_directory "lib"
empty_directory_with_gitkeep "lib/tasks"
+ empty_directory_with_gitkeep "lib/assets"
end
def log
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index ebe38bf8e6..88eea40b1b 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -5,13 +5,13 @@ source 'http://rubygems.org'
<%= database_gemfile_entry -%>
<%= "gem 'jruby-openssl'\n" if defined?(JRUBY_VERSION) -%>
-# Asset template engines
<%= "gem 'json'\n" if RUBY_VERSION < "1.9.2" -%>
-gem 'sass-rails'
-gem 'coffee-script'
-gem 'uglifier'
-<%= gem_for_javascript %>
+# Gems used only for assets and not required
+# in production environments by default.
+<%= assets_gemfile_entry %>
+
+<%= javascript_gemfile_entry %>
# Use unicorn as the web server
# gem 'unicorn'
@@ -20,6 +20,6 @@ gem 'uglifier'
# gem 'capistrano'
# To use debugger
-# <%= gem_for_ruby_debugger %>
+# <%= ruby_debugger_gemfile_entry %>
-<%= gem_for_turn -%>
+<%= turn_gemfile_entry -%>
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 37c2fb1263..eaa31e7386 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -8,12 +8,14 @@ require 'rails/all'
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
+<%= comment_if :skip_sprockets %> require "sprockets/railtie"
<%= comment_if :skip_test_unit %> require "rails/test_unit/railtie"
<% end -%>
-# If you have a Gemfile, require the gems listed there, including any gems
-# you've limited to :test, :development, or :production.
-Bundler.require(:default, Rails.env) if defined?(Bundler)
+# If you have a Gemfile, require the default gems, the ones in the
+# current environment and also include :assets gems if in development
+# or test environments.
+Bundler.require *Rails.groups(:assets => %w(development test)) if defined?(Bundler)
module <%= app_const_base %>
class Application < Rails::Application
@@ -45,7 +47,9 @@ module <%= app_const_base %>
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
+ <% unless options.skip_sprockets? %>
# Enable the asset pipeline
config.assets.enabled = true
+ <% end %>
end
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
new file mode 100644
index 0000000000..1d2bf08b91
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
@@ -0,0 +1,62 @@
+# If you are using mssql, derby, hsqldb, or h2 with one of the
+# ActiveRecord JDBC adapters, install the appropriate driver, e.g.,:
+# gem install activerecord-jdbcmssql-adapter
+#
+# Configure using Gemfile:
+# gem 'activerecord-jdbcmssql-adapter'
+#
+#development:
+# adapter: mssql
+# username: <%= app_name %>
+# password:
+# host: localhost
+# database: <%= app_name %>_development
+#
+# Warning: The database defined as "test" will be erased and
+# re-generated from your development database when you run "rake".
+# Do not set this db to the same as development or production.
+#
+#test:
+# adapter: mssql
+# username: <%= app_name %>
+# password:
+# host: localhost
+# database: <%= app_name %>_test
+#
+#production:
+# adapter: mssql
+# username: <%= app_name %>
+# password:
+# host: localhost
+# database: <%= app_name %>_production
+
+# If you are using oracle, db2, sybase, informix or prefer to use the plain
+# JDBC adapter, configure your database setting as the example below (requires
+# you to download and manually install the database vendor's JDBC driver .jar
+# file). See your driver documentation for the apropriate driver class and
+# connection string:
+
+development:
+ adapter: jdbc
+ username: <%= app_name %>
+ password:
+ driver:
+ url: jdbc:db://localhost/<%= app_name %>_development
+
+# Warning: The database defined as "test" will be erased and
+# re-generated from your development database when you run "rake".
+# Do not set this db to the same as development or production.
+
+test:
+ adapter: jdbc
+ username: <%= app_name %>
+ password:
+ driver:
+ url: jdbc:db://localhost/<%= app_name %>_test
+
+production:
+ adapter: jdbc
+ username: <%= app_name %>
+ password:
+ driver:
+ url: jdbc:db://localhost/<%= app_name %>_production
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
index 6bf83e86a5..5a594ac1f3 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
@@ -9,7 +9,7 @@
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
- adapter: jdbcmysql
+ adapter: mysql
database: <%= app_name %>_development
username: root
password:
@@ -19,14 +19,14 @@ development:
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: jdbcmysql
+ adapter: mysql
database: <%= app_name %>_test
username: root
password:
host: localhost
production:
- adapter: jdbcmysql
+ adapter: mysql
database: <%= app_name %>_production
username: root
password:
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
index 0c7f45322b..fe9466b366 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
@@ -1,19 +1,10 @@
-# PostgreSQL. Versions 7.4 and 8.x are supported.
-#
-# Install the pg driver:
-# gem install pg
-# On Mac OS X with macports:
-# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
-# On Windows:
-# gem install pg
-# Choose the win32 build.
-# Install PostgreSQL and put its /bin directory on your path.
+# PostgreSQL. Versions 8.2 and up are supported.
#
# Configure Using Gemfile
# gem 'activerecord-jdbcpostgresql-adapter'
development:
- adapter: jdbcpostgresql
+ adapter: postgresql
encoding: unicode
database: <%= app_name %>_development
username: <%= app_name %>
@@ -38,14 +29,14 @@ development:
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: jdbcpostgresql
+ adapter: postgresql
encoding: unicode
database: <%= app_name %>_test
username: <%= app_name %>
password:
production:
- adapter: jdbcpostgresql
+ adapter: postgresql
encoding: unicode
database: <%= app_name %>_production
username: <%= app_name %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
index 6d241d57ae..175f3eb3db 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
@@ -5,16 +5,16 @@
# gem 'activerecord-jdbcsqlite3-adapter'
#
development:
- adapter: jdbcsqlite3
+ adapter: sqlite3
database: db/development.sqlite3
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: jdbcsqlite3
+ adapter: sqlite3
database: db/test.sqlite3
production:
- adapter: jdbcsqlite3
+ adapter: sqlite3
database: db/production.sqlite3
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
index 467dfc3956..f08f86aac3 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
@@ -1,4 +1,4 @@
-# PostgreSQL. Versions 7.4 and 8.x are supported.
+# PostgreSQL. Versions 8.2 and up are supported.
#
# Install the pg driver:
# gem install pg
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 ffd9058238..3e0c29a587 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
@@ -22,6 +22,11 @@
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
+ <%- unless options.skip_active_record? -%>
+ # Raise exception on mass assignment protection for ActiveRecord models
+ config.active_record.mass_assignment_sanitizer = :strict
+ <%- end -%>
+
# Do not compress assets
config.assets.compress = false
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 60e26755fe..06ed890e05 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
@@ -14,9 +14,6 @@
# Compress JavaScripts and CSS
config.assets.compress = true
- # Specify the default JavaScript compressor
- config.assets.js_compressor = :uglifier
-
# Specifies the header that your server uses for sending files
# (comment out if your front-end server doesn't support this)
config.action_dispatch.x_sendfile_header = "X-Sendfile" # Use 'X-Accel-Redirect' for nginx
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 d50f536164..ea81748464 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
@@ -54,5 +54,5 @@
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
- # match ':controller(/:action(/:id(.:format)))'
+ # match ':controller(/:action(/:id))(.:format)'
end
diff --git a/railties/lib/rails/generators/rails/assets/assets_generator.rb b/railties/lib/rails/generators/rails/assets/assets_generator.rb
index db3422fe83..2e7f25a0b7 100644
--- a/railties/lib/rails/generators/rails/assets/assets_generator.rb
+++ b/railties/lib/rails/generators/rails/assets/assets_generator.rb
@@ -7,21 +7,14 @@ module Rails
class_option :javascript_engine, :desc => "Engine for JavaScripts"
class_option :stylesheet_engine, :desc => "Engine for Stylesheets"
- def create_javascript_files
- return unless options.javascripts?
- copy_file "javascript.#{javascript_extension}",
- File.join('app/assets/javascripts', class_path, "#{asset_name}.#{javascript_extension}")
- end
-
protected
def asset_name
file_name
end
- def javascript_extension
- options.javascript_engine.present? ?
- "js.#{options.javascript_engine}" : "js"
+ hook_for :javascript_engine do |javascript_engine|
+ invoke javascript_engine, [name] if options[:javascripts]
end
hook_for :stylesheet_engine do |stylesheet_engine|
diff --git a/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee b/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee
deleted file mode 100644
index 761567942f..0000000000
--- a/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
index 807350316c..7c0a2b9cf4 100644
--- a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
@@ -11,15 +11,15 @@ module Rails
def app
if mountable?
directory "app"
- template "#{app_templates_dir}/app/views/layouts/application.html.erb.tt",
+ template "app/views/layouts/application.html.erb.tt",
"app/views/layouts/#{name}/application.html.erb"
- empty_directory_with_gitkeep "app/assets/images"
+ empty_directory_with_gitkeep "app/assets/images/#{name}"
elsif full?
empty_directory_with_gitkeep "app/models"
empty_directory_with_gitkeep "app/controllers"
empty_directory_with_gitkeep "app/views"
empty_directory_with_gitkeep "app/helpers"
- empty_directory_with_gitkeep "app/assets/images"
+ empty_directory_with_gitkeep "app/assets/images/#{name}"
end
end
@@ -108,9 +108,9 @@ task :default => :test
def stylesheets
if mountable?
copy_file "#{app_templates_dir}/app/assets/stylesheets/application.css",
- "app/assets/stylesheets/application.css"
+ "app/assets/stylesheets/#{name}/application.css"
elsif full?
- empty_directory_with_gitkeep "app/assets/stylesheets"
+ empty_directory_with_gitkeep "app/assets/stylesheets/#{name}"
end
end
@@ -119,9 +119,9 @@ task :default => :test
if mountable?
template "#{app_templates_dir}/app/assets/javascripts/application.js.tt",
- "app/assets/javascripts/application.js"
+ "app/assets/javascripts/#{name}/application.js"
elsif full?
- empty_directory_with_gitkeep "app/assets/javascripts"
+ empty_directory_with_gitkeep "app/assets/javascripts/#{name}"
end
end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
index c28e568711..7e6eb18341 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
@@ -7,9 +7,8 @@ source "http://rubygems.org"
<% end -%>
<% if mountable? -%>
-<%= gem_for_javascript -%>
+<%= javascript_gemfile_entry -%>
<% end -%>
-if RUBY_VERSION < '1.9'
- gem "ruby-debug", ">= 0.10.3"
-end
+# To use debugger
+# <%= ruby_debugger_gemfile_entry %> \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt
new file mode 100644
index 0000000000..01550dec2f
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title><%= camelized %></title>
+ <%%= stylesheet_link_tag "<%= name %>/application" %>
+ <%%= javascript_include_tag "<%= name %>/application" %>
+ <%%= csrf_meta_tags %>
+</head>
+<body>
+
+<%%= yield %>
+
+</body>
+</html>
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
index 8b68280a5e..4864ead960 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
@@ -1,13 +1,15 @@
require File.expand_path('../boot', __FILE__)
-<% unless options[:skip_active_record] -%>
+<% if include_all_railties? -%>
require 'rails/all'
<% else -%>
-# require "active_record/railtie"
+# Pick the frameworks you want:
+<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
-require "rails/test_unit/railtie"
+<%= comment_if :skip_sprockets %> require "sprockets/railtie"
+<%= comment_if :skip_test_unit %> require "rails/test_unit/railtie"
<% end -%>
Bundler.require
diff --git a/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb b/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb
index e7a06e4a73..dea7e22196 100644
--- a/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb
+++ b/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb
@@ -1,8 +1,6 @@
require 'test_helper'
class <%= class_name %>Test < ActionDispatch::IntegrationTest
- fixtures :all
-
# test "the truth" do
# assert true
# end
diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb
index d05e031f56..a1e15092b2 100644
--- a/railties/lib/rails/info.rb
+++ b/railties/lib/rails/info.rb
@@ -78,6 +78,10 @@ module Rails
Rails::VERSION::STRING
end
+ property 'JavaScript Runtime' do
+ ExecJS.runtime.name
+ end
+
# Versions of each Rails framework (Active Record, Action Pack,
# Active Resource, Action Mailer, and Active Support).
frameworks.each do |framework|
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index 5f50943626..8c88b25617 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -84,7 +84,7 @@ module Rails
# == Loading rake tasks and generators
#
# If your railtie has rake tasks, you can tell Rails to load them through the method
- # rake tasks:
+ # rake_tasks:
#
# class MyRailtie < Rails::Railtie
# rake_tasks do
@@ -174,11 +174,11 @@ module Rails
def eager_load!
end
- def load_console(app)
+ def load_console(app=self)
self.class.console.each { |block| block.call(app) }
end
- def load_tasks(app)
+ def load_tasks(app=self)
extend Rake::DSL if defined? Rake::DSL
self.class.rake_tasks.each { |block| block.call(app) }
@@ -190,7 +190,7 @@ module Rails
end
end
- def load_generators(app)
+ def load_generators(app=self)
self.class.generators.each { |block| block.call(app) }
end
diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb
index 6d6e7f8b59..1eed763aa3 100644
--- a/railties/lib/rails/source_annotation_extractor.rb
+++ b/railties/lib/rails/source_annotation_extractor.rb
@@ -28,9 +28,9 @@ class SourceAnnotationExtractor
end
end
- # Prints all annotations with tag +tag+ under the root directories +app+, +lib+,
- # and +test+ (recursively). Only filenames with extension +.builder+, +.rb+,
- # +.rxml+, +.rhtml+, or +.erb+ are taken into account. The +options+
+ # Prints all annotations with tag +tag+ under the root directories +app+, +config+, +lib+,
+ # +script+, and +test+ (recursively). Only filenames with extension
+ # +.builder+, +.rb+, +.rxml+, +.rhtml+, or +.erb+ are taken into account. The +options+
# hash is passed to each annotation's +to_s+.
#
# This class method is the single entry point for the rake tasks.
@@ -49,7 +49,7 @@ class SourceAnnotationExtractor
# with their annotations. Only files with annotations are included, and only
# those with extension +.builder+, +.rb+, +.rxml+, +.rhtml+, and +.erb+
# are taken into account.
- def find(dirs=%w(app lib test))
+ def find(dirs=%w(app config lib script test))
dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
end
diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb
index 166d518f7c..9807000578 100644
--- a/railties/lib/rails/tasks.rb
+++ b/railties/lib/rails/tasks.rb
@@ -3,7 +3,6 @@ $VERBOSE = nil
# Load Rails rakefile extensions
%w(
annotations
- assets
documentation
framework
log
diff --git a/railties/lib/rails/tasks/assets.rake b/railties/lib/rails/tasks/assets.rake
deleted file mode 100644
index 4678ea460e..0000000000
--- a/railties/lib/rails/tasks/assets.rake
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace :assets do
- desc "Compile all the assets named in config.assets.precompile"
- task :precompile => :environment do
- # Give assets access to asset_path
- Sprockets::Helpers::RailsHelper
-
- assets = Rails.application.config.assets.precompile
- Rails.application.assets.precompile(*assets)
- end
-
- desc "Remove compiled assets"
- task :clean => :environment do
- assets = Rails.application.config.assets
- public_asset_path = Rails.public_path + assets.prefix
- file_list = FileList.new("#{public_asset_path}/*.js", "#{public_asset_path}/*.css")
- file_list.each do |file|
- rm file
- rm "#{file}.gz", :force => true
- end
- end
-end
diff --git a/railties/lib/rails/tasks/engine.rake b/railties/lib/rails/tasks/engine.rake
index 2f0e7be896..2152e811f5 100644
--- a/railties/lib/rails/tasks/engine.rake
+++ b/railties/lib/rails/tasks/engine.rake
@@ -67,3 +67,5 @@ def find_engine_path(path)
find_engine_path(File.expand_path('..', path))
end
end
+
+Rake.application.invoke_task(:load_app)
diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake
index 28dc40379b..b9877a83b5 100644
--- a/railties/lib/rails/test_unit/testing.rake
+++ b/railties/lib/rails/test_unit/testing.rake
@@ -79,10 +79,14 @@ task :test do
Rake::Task[task].invoke
nil
rescue => e
- task
+ { :task => task, :exception => e }
end
end.compact
- abort "Errors running #{errors * ', '}!" if errors.any?
+
+ if errors.any?
+ puts errors.map { |e| "Errors running #{e[:task]}! #{e[:exception].inspect}" }.join("\n")
+ abort
+ end
end
namespace :test do
diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb
index 3d6ecb9d30..254227ecf7 100644
--- a/railties/lib/rails/version.rb
+++ b/railties/lib/rails/version.rb
@@ -1,9 +1,9 @@
module Rails
module VERSION #:nodoc:
MAJOR = 3
- MINOR = 1
+ MINOR = 2
TINY = 0
- PRE = "rc1"
+ PRE = "beta"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/railties/railties.gemspec b/railties/railties.gemspec
index f1c92bd5d4..b917128885 100644
--- a/railties/railties.gemspec
+++ b/railties/railties.gemspec
@@ -15,11 +15,15 @@ Gem::Specification.new do |s|
s.files = Dir['CHANGELOG', 'README.rdoc', 'bin/**/*', 'guides/**/*', 'lib/**/{*,.[a-z]*}']
s.require_path = 'lib'
+ s.bindir = 'bin'
+ s.executables = ['rails']
+
s.rdoc_options << '--exclude' << '.'
s.add_dependency('rake', '>= 0.8.7')
s.add_dependency('thor', '~> 0.14.6')
s.add_dependency('rack-ssl', '~> 1.3.2')
+ s.add_dependency('rdoc', '~> 3.4')
s.add_dependency('activesupport', version)
s.add_dependency('actionpack', version)
end
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index 2b593005a2..e1eee71a9e 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -1,8 +1,9 @@
require 'isolation/abstract_unit'
+require 'active_support/core_ext/kernel/reporting'
require 'rack/test'
module ApplicationTests
- class RoutingTest < Test::Unit::TestCase
+ class AssetsTest < Test::Unit::TestCase
include ActiveSupport::Testing::Isolation
include Rack::Test::Methods
@@ -34,6 +35,45 @@ module ApplicationTests
assert_match "alert()", last_response.body
end
+ test "assets do not require compressors until it is used" do
+ app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
+ ENV["RAILS_ENV"] = "production"
+ require "#{app_path}/config/environment"
+
+ assert !defined?(Uglifier)
+ get "/assets/demo.js"
+ assert_match "alert()", last_response.body
+ assert defined?(Uglifier)
+ end
+
+ test "assets are compiled properly" do
+ app_file "app/assets/javascripts/application.js", "alert();"
+ app_file "app/assets/javascripts/foo/application.js", "alert();"
+
+ capture(:stdout) do
+ Dir.chdir(app_path){ `bundle exec rake assets:precompile` }
+ end
+ files = Dir["#{app_path}/public/assets/application-*.js"]
+ files << Dir["#{app_path}/public/assets/foo/application-*.js"].first
+ files.each do |file|
+ assert_not_nil file, "Expected application.js asset to be generated, but none found"
+ assert_equal "alert();\n", File.read(file)
+ end
+ end
+
+ test "assets are cleaned up properly" do
+ app_file "public/assets/application.js", "alert();"
+ app_file "public/assets/application.css", "a { color: green; }"
+ app_file "public/assets/subdir/broken.png", "not really an image file"
+
+ capture(:stdout) do
+ Dir.chdir(app_path){ `bundle exec rake assets:clean` }
+ end
+
+ files = Dir["#{app_path}/public/assets/**/*"]
+ assert_equal 0, files.length, "Expected no assets, but found #{files.join(', ')}"
+ end
+
test "does not stream session cookies back" do
app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 477dada820..448982f9de 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -39,6 +39,21 @@ module ApplicationTests
FileUtils.rm_rf(new_app) if File.directory?(new_app)
end
+ test "Rails.groups returns available groups" do
+ require "rails"
+
+ Rails.env = "development"
+ assert_equal [:default, "development"], Rails.groups
+ assert_equal [:default, "development", :assets], Rails.groups(:assets => [:development])
+ assert_equal [:default, "development", :another, :assets], Rails.groups(:another, :assets => %w(development))
+
+ Rails.env = "test"
+ assert_equal [:default, "test"], Rails.groups(:assets => [:development])
+
+ ENV["RAILS_GROUPS"] = "javascripts,stylesheets"
+ assert_equal [:default, "test", "javascripts", "stylesheets"], Rails.groups
+ end
+
test "Rails.application is nil until app is initialized" do
require 'rails'
assert_nil Rails.application
@@ -501,5 +516,14 @@ module ApplicationTests
get "/", { :format => :xml }, "HTTP_ACCEPT" => "application/xml"
assert_equal 'XML', last_response.body
end
+
+ test "Rails.application#env_config exists and include some existing parameters" do
+ make_basic_app
+
+ assert_respond_to app, :env_config
+ assert_equal app.env_config['action_dispatch.parameter_filter'], app.config.filter_parameters
+ assert_equal app.env_config['action_dispatch.secret_token'], app.config.secret_token
+ assert_equal app.env_config['action_dispatch.show_exceptions'], app.config.action_dispatch.show_exceptions
+ end
end
end
diff --git a/railties/test/application/initializers/i18n_test.rb b/railties/test/application/initializers/i18n_test.rb
index aa4db6e12a..8c2c079fb8 100644
--- a/railties/test/application/initializers/i18n_test.rb
+++ b/railties/test/application/initializers/i18n_test.rb
@@ -52,7 +52,7 @@ module ApplicationTests
end
test "locale files should be added to the load path" do
- app_file "config/another_locale.yml", ""
+ app_file "config/another_locale.yml", "en:\nfoo: ~"
add_to_config <<-RUBY
config.i18n.load_path << config.root.join("config/another_locale.yml").to_s
@@ -131,7 +131,7 @@ en:
# Fallbacks
test "not using config.i18n.fallbacks does not initialize I18n.fallbacks" do
- I18n.backend = Class.new { include I18n::Backend::Base }.new
+ I18n.backend = Class.new(I18n::Backend::Simple).new
load_app
assert_no_fallbacks
end
@@ -145,7 +145,7 @@ en:
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
+ I18n::Railtie.config.i18n.backend = Class.new(I18n::Backend::Simple).new
load_app
assert I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
assert_fallbacks :de => [:de, :en]
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index 44ac6615de..7671c129e9 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -59,6 +59,32 @@ module ApplicationTests
Dir.chdir(app_path){ `rake stats` }
end
+ def test_rake_test_error_output
+ Dir.chdir(app_path){ `rake db:migrate` }
+
+ app_file "config/database.yml", <<-RUBY
+ development:
+ RUBY
+
+ app_file "test/unit/one_unit_test.rb", <<-RUBY
+ RUBY
+
+ app_file "test/functional/one_functional_test.rb", <<-RUBY
+ raise RuntimeError
+ RUBY
+
+ app_file "test/integration/one_integration_test.rb", <<-RUBY
+ raise RuntimeError
+ RUBY
+
+ silence_stderr do
+ output = Dir.chdir(app_path){ `rake test` }
+ assert_match /Errors running test:units! #<ActiveRecord::AdapterNotSpecified/, output
+ assert_match /Errors running test:functionals! #<RuntimeError/, output
+ assert_match /Errors running test:integration! #<RuntimeError/, output
+ end
+ end
+
def test_rake_routes_output_strips_anchors_from_http_verbs
app_file "config/routes.rb", <<-RUBY
AppTemplate::Application.routes.draw do
@@ -125,5 +151,14 @@ module ApplicationTests
assert_equal 2, ::AppTemplate::Application::Product.count
assert_equal 0, ::AppTemplate::Application::User.count
end
+
+ def test_scaffold_tests_pass_by_default
+ content = Dir.chdir(app_path) do
+ `rails generate scaffold user username:string password:string`
+ `bundle exec rake db:migrate db:test:clone test`
+ end
+
+ assert_match(/7 tests, 10 assertions, 0 failures, 0 errors/, content)
+ end
end
-end
+end \ No newline at end of file
diff --git a/railties/test/application/runner_test.rb b/railties/test/application/runner_test.rb
index 4104bacae5..4468fa295e 100644
--- a/railties/test/application/runner_test.rb
+++ b/railties/test/application/runner_test.rb
@@ -22,6 +22,10 @@ module ApplicationTests
teardown_app
end
+ def test_should_include_runner_in_shebang_line_in_help_without_option
+ assert_match "/rails runner", Dir.chdir(app_path) { `bundle exec rails runner` }
+ end
+
def test_should_include_runner_in_shebang_line_in_help
assert_match "/rails runner", Dir.chdir(app_path) { `bundle exec rails runner --help` }
end
diff --git a/railties/test/fixtures/lib/generators/wrong_generator.rb b/railties/test/fixtures/lib/generators/wrong_generator.rb
deleted file mode 100644
index 6aa7cb052e..0000000000
--- a/railties/test/fixtures/lib/generators/wrong_generator.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# Old generator version
-class WrongGenerator < Rails::Generator::NamedBase
-end
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index c31c65a27d..81f0bf5e82 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -10,6 +10,7 @@ DEFAULT_APP_FILES = %w(
config.ru
app/assets/javascripts
app/assets/stylesheets
+ app/assets/images
app/controllers
app/helpers
app/mailers
@@ -22,8 +23,8 @@ DEFAULT_APP_FILES = %w(
doc
lib
lib/tasks
+ lib/assets
log
- app/assets/images
script/rails
test/fixtures
test/functional
@@ -47,11 +48,12 @@ class AppGeneratorTest < Rails::Generators::TestCase
::DEFAULT_APP_FILES
end
- def test_application_controller_and_layout_files
+ def test_assets
run_generator
assert_file "app/views/layouts/application.html.erb", /stylesheet_link_tag\s+"application"/
assert_file "app/views/layouts/application.html.erb", /javascript_include_tag\s+"application"/
assert_file "app/assets/stylesheets/application.css"
+ assert_file "config/application.rb", /config\.assets\.enabled = true/
end
def test_invalid_application_name_raises_an_error
@@ -123,18 +125,26 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_config_database_is_added_by_default
run_generator
assert_file "config/database.yml", /sqlite3/
- assert_file "Gemfile", /^gem\s+["']sqlite3["']$/
+ unless defined?(JRUBY_VERSION)
+ assert_file "Gemfile", /^gem\s+["']sqlite3["']$/
+ else
+ assert_file "Gemfile", /^gem\s+["']activerecord-jdbcsqlite3-adapter["']$/
+ end
end
def test_config_another_database
run_generator([destination_root, "-d", "mysql"])
assert_file "config/database.yml", /mysql/
- assert_file "Gemfile", /^gem\s+["']mysql2["']$/
+ unless defined?(JRUBY_VERSION)
+ assert_file "Gemfile", /^gem\s+["']mysql2["']$/
+ else
+ assert_file "Gemfile", /^gem\s+["']activerecord-jdbcmysql-adapter["']$/
+ end
end
def test_config_jdbcmysql_database
run_generator([destination_root, "-d", "jdbcmysql"])
- assert_file "config/database.yml", /jdbcmysql/
+ assert_file "config/database.yml", /mysql/
assert_file "Gemfile", /^gem\s+["']activerecord-jdbcmysql-adapter["']$/
# TODO: When the JRuby guys merge jruby-openssl in
# jruby this will be removed
@@ -143,28 +153,48 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_config_jdbcsqlite3_database
run_generator([destination_root, "-d", "jdbcsqlite3"])
- assert_file "config/database.yml", /jdbcsqlite3/
+ assert_file "config/database.yml", /sqlite3/
assert_file "Gemfile", /^gem\s+["']activerecord-jdbcsqlite3-adapter["']$/
end
def test_config_jdbcpostgresql_database
run_generator([destination_root, "-d", "jdbcpostgresql"])
- assert_file "config/database.yml", /jdbcpostgresql/
+ assert_file "config/database.yml", /postgresql/
assert_file "Gemfile", /^gem\s+["']activerecord-jdbcpostgresql-adapter["']$/
end
+ def test_config_jdbc_database
+ run_generator([destination_root, "-d", "jdbc"])
+ assert_file "config/database.yml", /jdbc/
+ assert_file "config/database.yml", /mssql/
+ assert_file "Gemfile", /^gem\s+["']activerecord-jdbc-adapter["']$/
+ end
+
+ def test_config_jdbc_database_when_no_option_given
+ if defined?(JRUBY_VERSION)
+ run_generator([destination_root])
+ assert_file "config/database.yml", /sqlite3/
+ assert_file "Gemfile", /^gem\s+["']activerecord-jdbcsqlite3-adapter["']$/
+ end
+ end
+
def test_generator_if_skip_active_record_is_given
run_generator [destination_root, "--skip-active-record"]
assert_no_file "config/database.yml"
+ assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
assert_file "test/test_helper.rb" do |helper_content|
assert_no_match(/fixtures :all/, helper_content)
end
assert_file "test/performance/browsing_test.rb"
end
- def test_active_record_is_removed_from_frameworks_if_skip_active_record_is_given
- run_generator [destination_root, "--skip-active-record"]
- assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
+ def test_generator_if_skip_active_record_is_given
+ run_generator [destination_root, "--skip-sprockets"]
+ assert_file "config/application.rb" do |content|
+ assert_match(/#\s+require\s+["']sprockets\/railtie["']/, content)
+ assert_no_match(/config\.assets\.enabled = true/, content)
+ end
+ assert_file "test/performance/browsing_test.rb"
end
def test_creation_of_a_test_directory
diff --git a/railties/test/generators/assets_generator_test.rb b/railties/test/generators/assets_generator_test.rb
index 2d20982d04..044e0b6bc6 100644
--- a/railties/test/generators/assets_generator_test.rb
+++ b/railties/test/generators/assets_generator_test.rb
@@ -8,19 +8,13 @@ class AssetsGeneratorTest < Rails::Generators::TestCase
def test_assets
run_generator
- assert_file "app/assets/javascripts/posts.js.coffee"
+ assert_file "app/assets/javascripts/posts.js"
assert_file "app/assets/stylesheets/posts.css"
end
def test_skipping_assets
content = run_generator ["posts", "--no-stylesheets", "--no-javascripts"]
- assert_no_file "app/assets/javascripts/posts.js.coffee"
+ assert_no_file "app/assets/javascripts/posts.js"
assert_no_file "app/assets/stylesheets/posts.css"
end
-
- def test_vanilla_assets
- run_generator ["posts", "--no-javascript-engine"]
- assert_file "app/assets/javascripts/posts.js"
- assert_file "app/assets/stylesheets/posts.css"
- end
end
diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb
index 3adf7be118..c3fa9ebb03 100644
--- a/railties/test/generators/controller_generator_test.rb
+++ b/railties/test/generators/controller_generator_test.rb
@@ -39,7 +39,7 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
def test_invokes_assets
run_generator
- assert_file "app/assets/javascripts/account.js.coffee"
+ assert_file "app/assets/javascripts/account.js"
assert_file "app/assets/stylesheets/account.css"
end
diff --git a/railties/test/generators/generated_attribute_test.rb b/railties/test/generators/generated_attribute_test.rb
index 0d2e624f44..c9f8ab0a7b 100644
--- a/railties/test/generators/generated_attribute_test.rb
+++ b/railties/test/generators/generated_attribute_test.rb
@@ -113,15 +113,8 @@ class GeneratedAttributeTest < Rails::Generators::TestCase
end
end
- def test_nil_type_raises_exception
- assert_raise Thor::Error do
- create_generated_attribute(nil, 'title')
- end
- end
-
- def test_missing_type_raises_exception
- assert_raise Thor::Error do
- create_generated_attribute('', 'title')
- end
+ def test_blank_type_defaults_to_string_raises_exception
+ assert_equal :string, create_generated_attribute(nil, 'title').type
+ assert_equal :string, create_generated_attribute("", 'title').type
end
end
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
index 8c5ba9926b..1b0cb425c6 100644
--- a/railties/test/generators/model_generator_test.rb
+++ b/railties/test/generators/model_generator_test.rb
@@ -12,9 +12,15 @@ class ModelGeneratorTest < Rails::Generators::TestCase
end
def test_model_with_missing_attribute_type
- content = capture(:stderr) { run_generator ["post", "title:string", "body"] }
- assert_match(/Missing type for attribute 'body'/, content)
- assert_match(/Example: 'body:string' where string is the type/, content)
+ run_generator ["post", "title", "body:text", "author"]
+
+ assert_migration "db/migrate/create_posts.rb" do |m|
+ assert_method :change, m do |up|
+ assert_match(/t\.string :title/, up)
+ assert_match(/t\.text :body/, up)
+ assert_match(/t\.string :author/, up)
+ end
+ end
end
def test_invokes_default_orm
diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb
index 283d99dd9e..4bd77ff7e3 100644
--- a/railties/test/generators/plugin_new_generator_test.rb
+++ b/railties/test/generators/plugin_new_generator_test.rb
@@ -66,7 +66,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
assert_no_file "test"
end
- def test_database_entry_is_assed_by_default_in_full_mode
+ def test_database_entry_is_generated_for_sqlite3_by_default_in_full_mode
run_generator([destination_root, "--full"])
assert_file "test/dummy/config/database.yml", /sqlite/
assert_file "Gemfile", /^gem\s+["']sqlite3["']$/
@@ -101,19 +101,19 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
def test_skipping_javascripts_without_mountable_option
run_generator
- assert_no_file "app/assets/javascripts/application.js"
+ assert_no_file "app/assets/javascripts/bukkits/application.js"
assert_no_file "vendor/assets/javascripts/jquery.js"
assert_no_file "vendor/assets/javascripts/jquery_ujs.js"
end
def test_javascripts_generation
run_generator [destination_root, "--mountable"]
- assert_file "app/assets/javascripts/application.js"
+ assert_file "app/assets/javascripts/bukkits/application.js"
end
def test_jquery_is_the_default_javascript_library
run_generator [destination_root, "--mountable"]
- assert_file "app/assets/javascripts/application.js" do |contents|
+ assert_file "app/assets/javascripts/bukkits/application.js" do |contents|
assert_match %r{^//= require jquery}, contents
assert_match %r{^//= require jquery_ujs}, contents
end
@@ -124,7 +124,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
def test_other_javascript_libraries
run_generator [destination_root, "--mountable", '-j', 'prototype']
- assert_file "app/assets/javascripts/application.js" do |contents|
+ assert_file "app/assets/javascripts/bukkits/application.js" do |contents|
assert_match %r{^//= require prototype}, contents
assert_match %r{^//= require prototype_ujs}, contents
end
@@ -135,7 +135,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
def test_skip_javascripts
run_generator [destination_root, "--skip-javascript", "--mountable"]
- assert_no_file "app/assets/javascripts/application.js"
+ assert_no_file "app/assets/javascripts/bukkits/application.js"
assert_no_file "vendor/assets/javascripts/jquery.js"
assert_no_file "vendor/assets/javascripts/jquery_ujs.js"
end
@@ -159,11 +159,19 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
assert_match(/1 tests, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`)
end
+ def test_ensure_that_migration_tasks_work_with_mountable_option
+ run_generator [destination_root, "--mountable"]
+ FileUtils.cd destination_root
+ quietly { system 'bundle install' }
+ `bundle exec rake db:migrate`
+ assert_equal 0, $?.exitstatus
+ end
+
def test_creating_engine_in_full_mode
run_generator [destination_root, "--full"]
- assert_file "app/assets/javascripts"
- assert_file "app/assets/stylesheets"
- assert_file "app/assets/images"
+ assert_file "app/assets/javascripts/bukkits"
+ assert_file "app/assets/stylesheets/bukkits"
+ assert_file "app/assets/images/bukkits"
assert_file "app/models"
assert_file "app/controllers"
assert_file "app/views"
@@ -180,15 +188,19 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
def test_create_mountable_application_with_mountable_option
run_generator [destination_root, "--mountable"]
- assert_file "app/assets/javascripts"
- assert_file "app/assets/stylesheets"
- assert_file "app/assets/images"
+ assert_file "app/assets/javascripts/bukkits"
+ assert_file "app/assets/stylesheets/bukkits"
+ assert_file "app/assets/images/bukkits"
assert_file "config/routes.rb", /Bukkits::Engine.routes.draw do/
assert_file "lib/bukkits/engine.rb", /isolate_namespace Bukkits/
assert_file "test/dummy/config/routes.rb", /mount Bukkits::Engine => "\/bukkits"/
assert_file "app/controllers/bukkits/application_controller.rb", /module Bukkits\n class ApplicationController < ActionController::Base/
assert_file "app/helpers/bukkits/application_helper.rb", /module Bukkits\n module ApplicationHelper/
- assert_file "app/views/layouts/bukkits/application.html.erb", /<title>Bukkits<\/title>/
+ assert_file "app/views/layouts/bukkits/application.html.erb" do |contents|
+ assert_match "<title>Bukkits</title>", contents
+ assert_match /stylesheet_link_tag\s+['"]bukkits\/application['"]/, contents
+ assert_match /javascript_include_tag\s+['"]bukkits\/application['"]/, contents
+ end
end
def test_creating_gemspec
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index 2135ffac81..2db8090621 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -81,7 +81,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Assets
assert_file "app/assets/stylesheets/scaffold.css"
- assert_file "app/assets/javascripts/product_lines.js.coffee"
+ assert_file "app/assets/javascripts/product_lines.js"
assert_file "app/assets/stylesheets/product_lines.css"
end
@@ -114,7 +114,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Assets
assert_file "app/assets/stylesheets/scaffold.css", /:visited/
- assert_no_file "app/assets/javascripts/product_lines.js.coffee"
+ assert_no_file "app/assets/javascripts/product_lines.js"
assert_no_file "app/assets/stylesheets/product_lines.css"
end
@@ -190,7 +190,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Assets
assert_file "app/assets/stylesheets/scaffold.css", /:visited/
- assert_file "app/assets/javascripts/admin/roles.js.coffee"
+ assert_file "app/assets/javascripts/admin/roles.js"
assert_file "app/assets/stylesheets/admin/roles.css"
end
@@ -224,7 +224,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Assets
assert_file "app/assets/stylesheets/scaffold.css"
- assert_no_file "app/assets/javascripts/admin/roles.js.coffee"
+ assert_no_file "app/assets/javascripts/admin/roles.js"
assert_no_file "app/assets/stylesheets/admin/roles.css"
end
@@ -246,34 +246,33 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
def test_scaffold_generator_no_assets
run_generator [ "posts", "--no-assets" ]
assert_file "app/assets/stylesheets/scaffold.css"
- assert_no_file "app/assets/javascripts/posts.js.coffee"
+ assert_no_file "app/assets/javascripts/posts.js"
assert_no_file "app/assets/stylesheets/posts.css"
end
def test_scaffold_generator_no_stylesheets
run_generator [ "posts", "--no-stylesheets" ]
assert_no_file "app/assets/stylesheets/scaffold.css"
- assert_file "app/assets/javascripts/posts.js.coffee"
+ assert_file "app/assets/javascripts/posts.js"
assert_no_file "app/assets/stylesheets/posts.css"
end
def test_scaffold_generator_no_javascripts
run_generator [ "posts", "--no-javascripts" ]
assert_file "app/assets/stylesheets/scaffold.css"
- assert_no_file "app/assets/javascripts/posts.js.coffee"
- assert_file "app/assets/stylesheets/posts.css"
- end
-
- def test_scaffold_generator_no_engines
- run_generator [ "posts", "--no-javascript-engine" ]
- assert_file "app/assets/stylesheets/scaffold.css"
- assert_file "app/assets/javascripts/posts.js"
+ assert_no_file "app/assets/javascripts/posts.js"
assert_file "app/assets/stylesheets/posts.css"
end
def test_scaffold_generator_outputs_error_message_on_missing_attribute_type
- content = capture(:stderr) { run_generator ["post", "title:string", "body"]}
- assert_match(/Missing type for attribute 'body'/, content)
- assert_match(/Example: 'body:string' where string is the type/, content)
+ run_generator ["post", "title", "body:text", "author"]
+
+ assert_migration "db/migrate/create_posts.rb" do |m|
+ assert_method :change, m do |up|
+ assert_match(/t\.string :title/, up)
+ assert_match(/t\.text :body/, up)
+ assert_match(/t\.string :author/, up)
+ end
+ end
end
end
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index 301ae80bcf..56329f3183 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -88,12 +88,6 @@ class GeneratorsTest < Rails::Generators::TestCase
assert Rails::Generators.find_by_namespace(:model)
end
- def test_find_by_namespace_show_warning_if_generator_cant_be_loaded
- output = capture(:stderr) { Rails::Generators.find_by_namespace(:wrong) }
- assert_match(/\[WARNING\] Could not load generator/, output)
- assert_match(/Rails 2\.x generator/, output)
- end
-
def test_invoke_with_nested_namespaces
model_generator = mock('ModelGenerator') do
expects(:start).with(["Account"], {})
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 0a203fd4d0..685d1b154b 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -238,6 +238,10 @@ module TestHelpers
end
end
+ def remove_file(path)
+ FileUtils.rm_rf "#{app_path}/#{path}"
+ end
+
def controller(name, contents)
app_file("app/controllers/#{name}_controller.rb", contents)
end
diff --git a/railties/test/railties/generators_test.rb b/railties/test/railties/generators_test.rb
index fe59dcd52b..1d4ba0e5b6 100644
--- a/railties/test/railties/generators_test.rb
+++ b/railties/test/railties/generators_test.rb
@@ -1,7 +1,8 @@
RAILS_ISOLATED_ENGINE = true
require "isolation/abstract_unit"
-require "#{RAILS_FRAMEWORK_ROOT}/railties/lib/rails/generators/test_case"
+require 'generators/generators_test_helper'
+require "rails/generators/test_case"
module RailtiesTests
class GeneratorTest < Rails::Generators::TestCase
@@ -31,8 +32,8 @@ module RailtiesTests
end
def build_engine(is_mountable=false)
+ FileUtils.rm_rf(engine_path)
FileUtils.mkdir_p(engine_path)
- FileUtils.rm_r(engine_path)
mountable = is_mountable ? "--mountable" : ""
diff --git a/railties/test/railties/shared_tests.rb b/railties/test/railties/shared_tests.rb
index d8ea58166e..9a64b7c64e 100644
--- a/railties/test/railties/shared_tests.rb
+++ b/railties/test/railties/shared_tests.rb
@@ -53,6 +53,9 @@ module RailtiesTest
add_to_config "ActiveRecord::Base.timestamped_migrations = false"
+ boot_rails
+ railties = Rails.application.railties.all.map(&:railtie_name)
+
Dir.chdir(app_path) do
output = `bundle exec rake bukkits:install:migrations`
@@ -63,12 +66,16 @@ module RailtiesTest
assert_match /NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/, output
assert_equal 3, Dir["#{app_path}/db/migrate/*.rb"].length
- output = `bundle exec rake railties:install:migrations`
+ output = `bundle exec rake railties:install:migrations`.split("\n")
assert File.exists?("#{app_path}/db/migrate/4_create_yaffles.rb")
- assert_match /NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/, output
- assert_match /Copied migration 4_create_yaffles.rb from acts_as_yaffle/, output
- assert_no_match /2_create_users/, output
+ assert_no_match /2_create_users/, output.join("\n")
+
+ yaffle_migration_order = output.index(output.detect{|o| /Copied migration 4_create_yaffles.rb from acts_as_yaffle/ =~ o })
+ bukkits_migration_order = output.index(output.detect{|o| /NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/ =~ o })
+ assert_not_nil yaffle_migration_order, "Expected migration to be copied"
+ assert_not_nil bukkits_migration_order, "Expected migration to be skipped"
+ assert_equal (railties.index('acts_as_yaffle') > railties.index('bukkits')) , (yaffle_migration_order > bukkits_migration_order)
migrations_count = Dir["#{app_path}/db/migrate/*.rb"].length
output = `bundle exec rake railties:install:migrations`
@@ -77,6 +84,15 @@ module RailtiesTest
end
end
+ def test_no_rake_task_without_migrations
+ boot_rails
+ require 'rake'
+ require 'rdoc/task'
+ require 'rake/testtask'
+ Rails.application.load_tasks
+ assert !Rake::Task.task_defined?('bukkits:install:migrations')
+ end
+
def test_puts_its_lib_directory_on_load_path
boot_rails
require "another"