aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/guides/source/action_controller_overview.textile2
-rw-r--r--railties/guides/source/action_view_overview.textile238
-rw-r--r--railties/guides/source/active_record_querying.textile8
-rw-r--r--railties/guides/source/active_record_validations_callbacks.textile20
-rw-r--r--railties/guides/source/active_support_core_extensions.textile56
-rw-r--r--railties/guides/source/ajax_on_rails.textile4
-rw-r--r--railties/guides/source/caching_with_rails.textile12
-rw-r--r--railties/guides/source/command_line.textile9
-rw-r--r--railties/guides/source/configuring.textile2
-rw-r--r--railties/guides/source/contributing_to_ruby_on_rails.textile16
-rw-r--r--railties/guides/source/debugging_rails_applications.textile35
-rw-r--r--railties/guides/source/form_helpers.textile6
-rw-r--r--railties/guides/source/generators.textile4
-rw-r--r--railties/guides/source/getting_started.textile32
-rw-r--r--railties/guides/source/i18n.textile16
-rw-r--r--railties/guides/source/index.html.erb2
-rw-r--r--railties/guides/source/initialization.textile20
-rw-r--r--railties/guides/source/layouts_and_rendering.textile8
-rw-r--r--railties/guides/source/migrations.textile4
-rw-r--r--railties/guides/source/plugins.textile46
-rw-r--r--railties/guides/source/rails_application_templates.textile44
-rw-r--r--railties/guides/source/routing.textile6
-rw-r--r--railties/guides/source/ruby_on_rails_guides_guidelines.textile2
-rw-r--r--railties/guides/source/security.textile37
-rw-r--r--railties/guides/source/testing.textile4
-rw-r--r--railties/lib/rails/application.rb47
-rw-r--r--railties/lib/rails/application/configuration.rb21
-rw-r--r--railties/lib/rails/application/finisher.rb27
-rw-r--r--railties/lib/rails/engine.rb101
-rw-r--r--railties/lib/rails/engine/configuration.rb11
-rw-r--r--railties/lib/rails/generators.rb10
-rw-r--r--railties/lib/rails/generators/app_base.rb6
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb15
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png (renamed from railties/lib/rails/generators/rails/app/templates/public/images/rails.png)bin6646 -> 6646 bytes
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt18
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml30
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml17
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/db/seeds.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/index.html2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/test_helper.rb (renamed from railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt)0
-rw-r--r--railties/lib/rails/generators/rails/assets/assets_generator.rb48
-rw-r--r--railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee6
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb72
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory0
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb7
-rw-r--r--railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb21
-rw-r--r--railties/lib/rails/generators/rails/scaffold/templates/scaffold.css (renamed from railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css)0
-rw-r--r--railties/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss (renamed from railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css.scss)0
-rw-r--r--railties/lib/rails/generators/rails/stylesheets/USAGE5
-rw-r--r--railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb23
-rw-r--r--railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb7
-rw-r--r--railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb7
-rw-r--r--railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb7
-rw-r--r--railties/lib/rails/generators/test_unit/model/templates/unit_test.rb7
-rw-r--r--railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb7
-rw-r--r--railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt7
-rw-r--r--railties/lib/rails/railtie/configuration.rb7
-rw-r--r--railties/lib/rails/tasks.rb1
-rw-r--r--railties/lib/rails/tasks/assets.rake6
-rw-r--r--railties/lib/rails/tasks/railties.rake29
-rw-r--r--railties/test/application/configuration_test.rb12
-rw-r--r--railties/test/generators/app_generator_test.rb57
-rw-r--r--railties/test/generators/assets_generator_test.rb28
-rw-r--r--railties/test/generators/controller_generator_test.rb4
-rw-r--r--railties/test/generators/namespaced_generators_test.rb8
-rw-r--r--railties/test/generators/plugin_new_generator_test.rb46
-rw-r--r--railties/test/generators/scaffold_generator_test.rb52
-rw-r--r--railties/test/generators/stylesheets_generator_test.rb23
-rw-r--r--railties/test/isolation/abstract_unit.rb3
-rw-r--r--railties/test/railties/engine_test.rb253
-rw-r--r--railties/test/railties/shared_tests.rb42
73 files changed, 928 insertions, 815 deletions
diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile
index 496dc7224b..f8b586c151 100644
--- a/railties/guides/source/action_controller_overview.textile
+++ b/railties/guides/source/action_controller_overview.textile
@@ -368,7 +368,7 @@ class UsersController < ApplicationController
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @users}
- format.json { render :json => @users}
+ format.json { render :json => @users}
end
end
end
diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile
index d0b3ee6bfc..172932fdab 100644
--- a/railties/guides/source/action_view_overview.textile
+++ b/railties/guides/source/action_view_overview.textile
@@ -20,7 +20,28 @@ Note: Some features of Action View are tied to Active Record, but that doesn't m
h3. Using Action View with Rails
-TODO...
+For each controller there is an associated directory in the <tt>app/views</tt> directory which holds the template files that make up the views associated with that controller. These files are used to display the view that results from each controller action.
+
+Let's take a look at what Rails does by default when creating a new resource using the scaffold generator:
+
+<shell>
+$ rails generate scaffold post
+ [...]
+ invoke scaffold_controller
+ create app/controllers/posts_controller.rb
+ invoke erb
+ create app/views/posts
+ create app/views/posts/index.html.erb
+ create app/views/posts/edit.html.erb
+ create app/views/posts/show.html.erb
+ create app/views/posts/new.html.erb
+ create app/views/posts/_form.html.erb
+ [...]
+</shell>
+
+There is a naming convention for views in Rails. Typically, the views share their name with the associated controller action, as you can see above.
+For example, the index controller action of the <tt>posts_controller.rb</tt> will use the <tt>index.html.erb</tt> view file in the <tt>app/views/posts</tt> directory.
+The complete HTML returned to the client is composed of a combination of this ERB file, a layout template that wraps it, and all the partials that the view may reference. Later on this guide you can find a more detailed documentation of each one of this three components.
h3. Using Action View outside of Rails
@@ -94,9 +115,213 @@ TODO needs a screenshot? I have one - not sure where to put it.
h3. Templates, Partials and Layouts
-TODO...
+As mentioned before, the final HTML output is a composition of three Rails elements: +Templates+, +Partials+ and +Layouts+.
+Find below a brief overview of each one of them.
+
+h4. Templates
+
+Action View templates can be written in several ways. If the template file has a <tt>.erb</tt> extension then it uses a mixture of ERB (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> extension then a fresh instance of <tt>Builder::XmlMarkup</tt> library is used.
+
+Rails supports multiple template systems and uses a file extension to distinguish amongst them. For example, an HTML file using the ERB template system will have <tt>.html.erb</tt> as a file extension.
+
+h5. ERB
+
+Within an ERB template Ruby code can be included using both +<% %>+ and +<%= %>+ tags. The +<% %>+ are used to execute Ruby code that does not return anything, such as conditions, loops or blocks, and the +<%= %>+ tags are used when you want output.
+
+Consider the following loop for names:
+
+<erb>
+<b>Names of all the people</b>
+<% @people.each do |person| %>
+ Name: <%= person.name %><br/>
+<% end %>
+</erb>
+
+The loop is setup in regular embedding tags +<% %>+ and the name is written using the output embedding tag +<%= %>+. Note that this is not just a usage suggestion, for Regular output functions like print or puts won't work with ERB templates. So this would be wrong:
+
+<erb>
+<%# WRONG %>
+Hi, Mr. <% puts "Frodo" %>
+</erb>
+
+To suppress leading and trailing whitespaces, you can use +<%-+ +-%>+ interchangeably with +<%+ and +%>+.
+
+h5. Builder
+
+Builder templates are a more programmatic alternative to ERB. They are especially useful for generating XML content. An XmlMarkup object named +xml+ is automatically made available to templates with a <tt>.builder</tt> extension.
+
+Here are some basic examples:
+
+<ruby>
+xml.em("emphasized")
+xml.em { xml.b("emph & bold") }
+xml.a("A Link", "href"=>"http://rubyonrails.org")
+xml.target("name"=>"compile", "option"=>"fast")
+</ruby>
+
+will produce
+
+<html>
+<em>emphasized</em>
+<em><b>emph &amp; bold</b></em>
+<a href="http://rubyonrails.org">A link</a>
+<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:
+
+<ruby>
+xml.div {
+ xml.h1(@person.name)
+ xml.p(@person.bio)
+}
+</ruby>
+
+would produce something like:
+
+<html>
+<div>
+ <h1>David Heinemeier Hansson</h1>
+ <p>A product of Danish Design during the Winter of '79...</p>
+</div>
+</html>
+
+A full-length RSS example actually used on Basecamp:
+
+<ruby>
+xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
+ xml.channel do
+ xml.title(@feed_title)
+ xml.link(@url)
+ xml.description "Basecamp: Recent items"
+ xml.language "en-us"
+ xml.ttl "40"
+
+ for item in @recent_items
+ xml.item do
+ xml.title(item_title(item))
+ xml.description(item_description(item)) if item_description(item)
+ xml.pubDate(item_pubDate(item))
+ xml.guid(@person.firm.account.url + @recent_items.url(item))
+ xml.link(@person.firm.account.url + @recent_items.url(item))
+ xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
+ end
+ end
+ end
+end
+</ruby>
+
+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.
+
+h4. Partials
-TODO see http://guides.rubyonrails.org/layouts_and_rendering.html
+Partial templates – usually just called "partials" – are another device for breaking the rendering process into more manageable chunks. With a partial, you can move the code for rendering a particular piece of a response to its own file.
+
+h5. Naming Partials
+
+To render a partial as part of a view, you use the +render+ method within the view:
+
+<ruby>
+<%= render "menu" %>
+</ruby>
+
+This will render a file named +_menu.html.erb+ at that point within the view is being rendered. Note the leading underscore character: partials are named with a leading underscore to distinguish them from regular views, even though they are referred to without the underscore. This holds true even when you're pulling in a partial from another folder:
+
+<ruby>
+<%= render "shared/menu" %>
+</ruby>
+
+That code will pull in the partial from +app/views/shared/_menu.html.erb+.
+
+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:
+
+<erb>
+<%= render "shared/ad_banner" %>
+
+<h1>Products</h1>
+
+<p>Here are a few of our fine products:</p>
+<% @products.each do |product| %>
+ <%= render :partial => "product", :locals => { :product => product } %>
+<% end %>
+
+<%= render "shared/footer" %>
+</erb>
+
+Here, the +_ad_banner.html.erb+ and +_footer.html.erb+ partials could contain content that is shared among many pages in your application. You don't need to see the details of these sections when you're concentrating on a particular page.
+
+h5. The :as and :object options
+
+By default <tt>ActionView::Partials::PartialRenderer</tt> has its object in a local variable with the same name as the template. So, given
+
+<erb>
+<%= render :partial => "product" %>
+</erb>
+
+within product we'll get <tt>@product</tt> in the local variable +product+, as if we had written:
+
+<erb>
+<%= render :partial => "product", :locals => { :product => @product } %>
+</erb>
+
+With the <tt>:as</tt> option we can specify a different name for said local variable. For example, if we wanted it to be +item+ instead of product+ we'd do:
+
+<erb>
+<%= render :partial => "product", :as => 'item' %>
+</erb>
+
+The <tt>:object</tt> option can be used to directly specify which object is rendered into the partial; useful when the template's object is elsewhere, in a different ivar or in a local variable for instance.
+
+For example, instead of:
+
+<erb>
+<%= render :partial => "product", :locals => { :product => @item } %>
+</erb>
+
+you'd do:
+
+<erb>
+<%= render :partial => "product", :object => @item %>
+</erb>
+
+The <tt>:object</tt> and <tt>:as</tt> options can be used together.
+
+h5. Rendering Collections
+
+The example of partial use describes a familiar pattern where a template needs to iterate over an array and render a sub template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders a partial by the same name as the elements contained within.
+So the three-lined example for rendering all the products can be rewritten with a single line:
+
+<erb>
+<%= render :partial => "product", :collection => @products %>
+</erb>
+
+When a partial is called with a pluralized collection, then the individual instances of the partial have access to the member of the collection being rendered via a variable named after the partial. In this case, the partial is +_product+ , and within the +_product+ partial, you can refer to +product+ to get the instance that is being rendered.
+
+You can use a shorthand syntax for rendering collections. Assuming @products is a collection of +Product+ instances, you can simply write the following to produce the same result:
+
+<erb>
+<%= render @products %>
+</erb>
+
+Rails determines the name of the partial to use by looking at the model name in the collection. In fact, you can even create a heterogeneous collection and render it this way, and Rails will choose the proper partial for each member of the collection.
+
+h5. Spacer Templates
+
+You can also specify a second partial to be rendered between instances of the main partial by using the +:spacer_template+ option:
+
+<erb>
+<%= render @products, :spacer_template => "product_ruler" %>
+</erb>
+
+Rails will render the +_product_ruler+ partial (with no data passed in to it) between each pair of +_product+ partials.
+
+h4. Layouts
+
+TODO...
h3. Using Templates, Partials and Layouts in "The Rails Way"
@@ -262,9 +487,9 @@ Register one or more stylesheet files to be included when symbol is passed to +s
ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :monkey => ["head", "body", "tail"]
stylesheet_link_tag :monkey # =>
- <link href="/stylesheets/head.css" media="screen" rel="stylesheet" type="text/css" />
- <link href="/stylesheets/body.css" media="screen" rel="stylesheet" type="text/css" />
- <link href="/stylesheets/tail.css" media="screen" rel="stylesheet" type="text/css" />
+ <link href="/stylesheets/head.css" media="screen" rel="stylesheet" type="text/css" />
+ <link href="/stylesheets/body.css" media="screen" rel="stylesheet" type="text/css" />
+ <link href="/stylesheets/tail.css" media="screen" rel="stylesheet" type="text/css" />
</ruby>
h5. auto_discovery_link_tag
@@ -1472,5 +1697,6 @@ You can read more about the Rails Internationalization (I18n) API "here":i18n.ht
h3. Changelog
+* April 16, 2011: Added 'Using Action View with Rails', 'Templates' and 'Partials' sections. "Sebastian Martinez":http://wyeworks.com
* September 3, 2009: Continuing work by Trevor Turk, leveraging the Action Pack docs and "What's new in Edge Rails":http://ryandaigle.com/articles/2007/8/3/what-s-new-in-edge-rails-partials-get-layouts
* April 5, 2009: Starting work by Trevor Turk, leveraging Mike Gunderloy's docs
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile
index df8e35ed33..2f0a51e868 100644
--- a/railties/guides/source/active_record_querying.textile
+++ b/railties/guides/source/active_record_querying.textile
@@ -418,7 +418,7 @@ SELECT viewable_by, locked FROM clients
Be careful because this also means you're initializing a model object with only the fields that you've selected. If you attempt to access a field that is not in the initialized record you'll receive:
<shell>
-ActiveRecord::MissingAttributeError: missing attribute: <attribute>
+ActiveModel::MissingAttributeError: missing attribute: <attribute>
</shell>
Where +&lt;attribute&gt;+ is the attribute you asked for. The +id+ method will not raise the +ActiveRecord::MissingAttributeError+, so just be careful when working with associations because they need the +id+ method to function properly.
@@ -546,7 +546,7 @@ Active Record provides two locking mechanisms:
h4. Optimistic Locking
-Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of conflicts with the data. It does this by checking whether another process has made changes to a record since it was opened. An +ActiveRecord::StaleObjectError+ exception is thrown if that has occurred and the update is ignored.
+Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of conflicts with the data. It does this by checking whether another process has made changes to a record since it was opened. An +ActiveRecord::StaleObjectError+ exception is thrown if that has occurred and the update is ignored.
<strong>Optimistic locking column</strong>
@@ -993,7 +993,7 @@ Client.count
# SELECT count(*) AS count_all FROM clients
</ruby>
-Or on a relation :
+Or on a relation:
<ruby>
Client.where(:first_name => 'Ryan').count
@@ -1060,7 +1060,7 @@ If you want to find the sum of a field for all records in your table you can cal
Client.sum("orders_count")
</ruby>
-For options, please see the parent section, "Calculations":#calculations.
+For options, please see the parent section, "Calculations":#calculations.
h3. Changelog
diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile
index c65dd52e48..19bd4ad0f1 100644
--- a/railties/guides/source/active_record_validations_callbacks.textile
+++ b/railties/guides/source/active_record_validations_callbacks.textile
@@ -552,6 +552,21 @@ class Account < ActiveRecord::Base
end
</ruby>
+h4. Grouping conditional validations
+
+Sometimes it is useful to have multiple validations use one condition, it can be easily achieved using +with_options+.
+
+<ruby>
+class User < ActiveRecord::Base
+ with_options :if => :is_admin? do |admin|
+ admin.validates_length_of :password, :minimum => 10
+ admin.validates_presence_of :email
+ end
+end
+</ruby>
+
+All validations inside of +with_options+ block will have automatically passed the condition +:if => :is_admin?+
+
h3. Creating Custom Validation Methods
When the built-in validation helpers are not enough for your needs, you can write your own validation methods.
@@ -882,8 +897,9 @@ The macro-style class methods can also receive a block. Consider using this styl
class User < ActiveRecord::Base
validates_presence_of :login, :email
- before_create {|user| user.name = user.login.capitalize
- if user.name.blank?}
+ before_create do |user|
+ user.name = user.login.capitalize if user.name.blank?
+ end
end
</ruby>
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index 3ba840c044..f89c83e4cd 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -442,9 +442,9 @@ require_library_or_gem('mysql')
NOTE: Defined in +active_support/core_ext/kernel/requires.rb+.
-h4. +in?+ and +either?+
+h4. +in?+
-The predicate +in?+ tests if an object is included in another object, and the predicate +either?+ tests if an object is included in a list of objects which will be passed as arguments.
+The predicate +in?+ tests if an object is included in another object. An +ArgumentError+ exception will be raised if the argument passed does not respond to +include?+.
Examples of +in?+:
@@ -454,14 +454,6 @@ Examples of +in?+:
25.in?(30..50) # => false
</ruby>
-Examples of +either?+:
-
-<ruby>
- 1.either?(1,2,3) # => true
- 5.either?(1,2,3) # => false
- [1,2,3].either?([1,2,3], 2, [3,4,5]) # => true
-</ruby>
-
NOTE: Defined in +active_support/core_ext/object/inclusion.rb+.
h3. Extensions to +Module+
@@ -1274,6 +1266,15 @@ WARNING: The option +:separator+ can't be a regexp.
NOTE: Defined in +active_support/core_ext/string/filters.rb+.
+h4. +inquiry+
+
+The <tt>inquiry</tt> method converts a string into a +StringInquirer+ object making equality checks prettier.
+
+<ruby>
+"production".inquiry.production? # => true
+"active".inquiry.inactive? # => false
+</ruby>
+
h4. Key-based Interpolation
In Ruby 1.9 the <tt>%</tt> string operator supports key-based interpolation, both formatted and unformatted:
@@ -2005,6 +2006,11 @@ Similarly, +from+ returns the tail from the element at the passed index on:
The methods +second+, +third+, +fourth+, and +fifth+ return the corresponding element (+first+ is built-in). Thanks to social wisdom and positive constructiveness all around, +forty_two+ is also available.
+<ruby>
+%w(a b c d).third # => c
+%w(a b c d).fifth # => nil
+</ruby>
+
NOTE: Defined in +active_support/core_ext/array/access.rb+.
h4. Random Access
@@ -2100,7 +2106,7 @@ h5. +to_xml+
The method +to_xml+ returns a string containing an XML representation of its receiver:
<ruby>
-Contributor.all(:limit => 2, :order => 'rank ASC').to_xml
+Contributor.limit(2).order(:rank).to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <contributors type="array">
@@ -2175,7 +2181,7 @@ The name of children nodes is by default the name of the root node singularized.
The default XML builder is a fresh instance of <tt>Builder::XmlMarkup</tt>. You can configure your own builder via the <tt>:builder</tt> option. The method also accepts options like <tt>:dasherize</tt> and friends, they are forwarded to the builder:
<ruby>
-Contributor.all(:limit => 2, :order => 'rank ASC').to_xml(:skip_types => true)
+Contributor.limit(2).order(:rank).to_xml(:skip_types => true)
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <contributors>
@@ -3415,11 +3421,11 @@ h4. +silence+
Silences every log level lesser to the specified one for the duration of the given block. Log level orders are: debug, info, error and fatal.
<ruby>
- logger = Logger.new("log/development.log")
- logger.silence(Logger::INFO) do
- logger.debug("In space, no one can hear you scream.")
- logger.info("Scream all you want, small mailman!")
- end
+logger = Logger.new("log/development.log")
+logger.silence(Logger::INFO) do
+ logger.debug("In space, no one can hear you scream.")
+ logger.info("Scream all you want, small mailman!")
+end
</ruby>
h4. +datetime_format=+
@@ -3427,17 +3433,17 @@ h4. +datetime_format=+
Modifies the datetime format output by the formatter class associated with this logger. If the formatter class does not have a +datetime_format+ method then this is ignored.
<ruby>
- class Logger::FormatWithTime < Logger::Formatter
- cattr_accessor(:datetime_format) { "%Y%m%d%H%m%S" }
+class Logger::FormatWithTime < Logger::Formatter
+ cattr_accessor(:datetime_format) { "%Y%m%d%H%m%S" }
- def self.call(severity, timestamp, progname, msg)
- "#{timestamp.strftime(datetime_format)} -- #{String === msg ? msg : msg.inspect}\n"
- end
+ def self.call(severity, timestamp, progname, msg)
+ "#{timestamp.strftime(datetime_format)} -- #{String === msg ? msg : msg.inspect}\n"
end
+end
- logger = Logger.new("log/development.log")
- logger.formatter = Logger::FormatWithTime
- logger.info("<- is the current time")
+logger = Logger.new("log/development.log")
+logger.formatter = Logger::FormatWithTime
+logger.info("<- is the current time")
</ruby>
NOTE: Defined in +active_support/core_ext/logger.rb+.
diff --git a/railties/guides/source/ajax_on_rails.textile b/railties/guides/source/ajax_on_rails.textile
index 38a63ea483..1566c23414 100644
--- a/railties/guides/source/ajax_on_rails.textile
+++ b/railties/guides/source/ajax_on_rails.textile
@@ -42,7 +42,7 @@ You are ready to add some AJAX love to your Rails app!
h4. The Quintessential AJAX Rails Helper: link_to_remote
-Let's start with what is probably the most often used helper: +link_to_remote+. It has an interesting feature from the documentation point of view: the options supplied to +link_to_remote+ are shared by all other AJAX helpers, so learning the mechanics and options of +link_to_remote+ is a great help when using other helpers.
+Let's start with what is probably the most often used helper: +link_to_remote+. It has an interesting feature from the documentation point of view: the options supplied to +link_to_remote+ are shared by all other AJAX helpers, so learning the mechanics and options of +link_to_remote+ is a great help when using other helpers.
The signature of +link_to_remote+ function is the same as that of the standard +link_to+ helper:
@@ -72,7 +72,7 @@ link_to_remote "Add to cart",
If the server returns 200, the output of the above example is equivalent to our first, simple one. However, in case of error, the element with the DOM id +error+ is updated rather than the +cart+ element.
-** *position* By default (i.e. when not specifying this option, like in the examples before) the repsonse is injected into the element with the specified DOM id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content - the only question is where to place the new content? This can specified by the +position+ parameter, with four possibilities:
+** *position* By default (i.e. when not specifying this option, like in the examples before) the repsonse is injected into the element with the specified DOM id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content - the only question is where to place the new content? This can specified by the +position+ parameter, with four possibilities:
*** +:before+ Inserts the response text just before the target element. More precisely, it creates a text node from the response and inserts it as the left sibling of the target element.
*** +:after+ Similar behavior to +:before+, but in this case the response is inserted after the target element.
*** +:top+ Inserts the text into the target element, before it's original content. If the target element was empty, this is equivalent with not specifying +:position+ at all.
diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile
index 297ba2d661..799339e674 100644
--- a/railties/guides/source/caching_with_rails.textile
+++ b/railties/guides/source/caching_with_rails.textile
@@ -25,7 +25,7 @@ h4. Page Caching
Page caching is a Rails mechanism which allows the request for a generated page to be fulfilled by the webserver (i.e. apache or nginx), without ever having to go through the Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be applied to every situation (such as pages that need authentication) and since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with.
-So, how do you enable this super-fast cache behavior? Simple, let's say you have a controller called +ProductsController+ and an +index+ action that lists all the products
+So, how do you enable this super-fast cache behavior? Simple, let's say you have a controller called +ProductsController+ and an +index+ action that lists all the products
<ruby>
class ProductsController < ActionController
@@ -152,7 +152,7 @@ expire_fragment('all_available_products')
h4. Sweepers
-Cache sweeping is a mechanism which allows you to get around having a ton of +expire_{page,action,fragment}+ calls in your code. It does this by moving all the work required to expire cached content into an +ActionController::Caching::Sweeper+ subclass. This class is an observer and looks for changes to an object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter.
+Cache sweeping is a mechanism which allows you to get around having a ton of +expire_{page,action,fragment}+ calls in your code. It does this by moving all the work required to expire cached content into an +ActionController::Caching::Sweeper+ subclass. This class is an observer and looks for changes to an object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter.
Continuing with our Product controller example, we could rewrite it with a sweeper like this:
@@ -230,9 +230,9 @@ class ProductsController < ActionController
end
</ruby>
-The second time the same query is run against the database, it's not actually going to hit the database. The first time the result is returned from the query it is stored in the query cache (in memory) and the second time it's pulled from memory.
+The second time the same query is run against the database, it's not actually going to hit the database. The first time the result is returned from the query it is stored in the query cache (in memory) and the second time it's pulled from memory.
-However, it's important to note that query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action. If you'd like to store query results in a more persistent fashion, you can in Rails by using low level caching.
+However, it's important to note that query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action. If you'd like to store query results in a more persistent fashion, you can in Rails by using low level caching.
h3. Cache Stores
@@ -322,7 +322,7 @@ You can use Hashes and Arrays of values as cache keys.
<ruby>
# This is a legal cache key
-Rails.cache.read(:site => "mysite", :owners => [owner_1, owner2])
+Rails.cache.read(:site => "mysite", :owners => [owner_1, owner_2])
</ruby>
The keys you use on +Rails.cache+ will not be the same as those actually used with the storage engine. They may be modified with a namespace or altered to fit technology backend constraints. This means, for instance, that you can't save values with +Rails.cache+ and then try to pull them out with the +memcache-client+ gem. However, you also don't need to worry about exceeding the memcached size limit or violating syntax rules.
@@ -352,7 +352,7 @@ class ProductsController < ApplicationController
# If the request is fresh (i.e. it's not modified) then you don't need to do
# 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.
+ # :not_modified. So that's it, you're done.
end
</ruby>
diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile
index 9d8a9caf08..ad36c6532e 100644
--- a/railties/guides/source/command_line.textile
+++ b/railties/guides/source/command_line.textile
@@ -8,10 +8,10 @@ Rails comes with every command line tool you'll need to
* Mess with objects through an interactive shell
* Profile and benchmark your new creation
-NOTE: This tutorial assumes you have basic Rails knowledge from reading the "Getting Started with Rails Guide":getting_started.html.
-
endprologue.
+NOTE: This tutorial assumes you have basic Rails knowledge from reading the "Getting Started with Rails Guide":getting_started.html.
+
WARNING. This Guide is based on Rails 3.0. Some of the code shown here will not work in earlier versions of Rails.
h3. Command Line Basics
@@ -144,10 +144,13 @@ $ rails generate controller Greetings hello
create app/helpers/greetings_helper.rb
invoke test_unit
create test/unit/helpers/greetings_helper_test.rb
+ invoke assets
+ create app/assets/javascripts/greetings.js
+ create app/assets/stylesheets/greetings.css
</shell>
-What all did this generate? It made sure a bunch of directories were in our application, and created a controller file, a functional test file, a helper for the view, and a view file.
+What all did this generate? It made sure a bunch of directories were in our application, and created a controller file, a view file, a functional test file, a helper for the view, a javascript file and a stylesheet file.
Check out the controller and modify it a little (in +app/controllers/greetings_controller.rb+):
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index 53460b8c36..d7069b31fc 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -229,6 +229,8 @@ h4. Configuring Active Record
* +config.active_record.lock_optimistically+ controls whether ActiveRecord will use optimistic locking. By default this is +true+.
+* +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 ActiveRecord will consider all +tinyint(1)+ columns in a MySQL database to be booleans. By default this is +true+.
diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile
index 1fcc4fd7e3..cbc4acfeca 100644
--- a/railties/guides/source/contributing_to_ruby_on_rails.textile
+++ b/railties/guides/source/contributing_to_ruby_on_rails.textile
@@ -314,14 +314,20 @@ You should not be the only person who looks at the code before you submit it. Yo
You might also want to check out the "RailsBridge BugMash":http://wiki.railsbridge.org/projects/railsbridge/wiki/BugMash as a way to get involved in a group effort to improve Rails. This can help you get started and help check your code when you're writing your first patches.
+h4. Create a Lighthouse Ticket
+
+Now create a ticket for your patch. Go to the "new ticket":http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/new page at Lighthouse. Fill in a reasonable title and description, as well as tag the ticket with the ‘patch’ tag and whatever other subject area tags make sense. Write down your ticket number, for you will need it in the following step.
+
h4. Commit Your Changes
When you're happy with the code on your computer, you need to commit the changes to git:
<shell>
-$ git commit -a -m "Here is a commit message"
+$ git commit -a -m "Here is a commit message [#ticket_number state:committed]"
</shell>
+NOTE: By adding '[#ticket_number state:committed]' at the end of your commit message, the ticket will automatically change its status to commited once your patch is pushed to the repository.
+
h4. Update master
It’s pretty likely that other changes to master have happened while you were working. Go get them:
@@ -361,13 +367,12 @@ $ git apply --check my_new_patch.diff
Please make sure the patch does not introduce whitespace errors:
<shell>
-$ git apply --whitespace=error-all mynew_patch.diff
+$ git apply --whitespace=error-all my_new_patch.diff
</shell>
+h4. Attach your Patch to the Lighthouse Ticket
-h4. Create a Lighthouse Ticket
-
-Now create a ticket with your patch. Go to the "new ticket":http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/new page at Lighthouse. Fill in a reasonable title and description, remember to attach your patch file, and tag the ticket with the ‘patch’ tag and whatever other subject area tags make sense.
+Now you need to update the ticket by attaching the patch file you just created.
h4. Get Some Feedback
@@ -385,6 +390,7 @@ All contributions, either via master or docrails, get credit in "Rails Contribut
h3. Changelog
+* April 14, 2001: Modified Contributing to the Rails Code section to add '[#ticket_number state:commited]' on patches commit messages by "Sebastian Martinez":http://wyeworks.com
* December 28, 2010: Complete revision by "Xavier Noria":credits.html#fxn
* April 6, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* August 1, 2009: Updates/amplifications by "Mike Gunderloy":credits.html#mgunderloy
diff --git a/railties/guides/source/debugging_rails_applications.textile b/railties/guides/source/debugging_rails_applications.textile
index fb17dccfb8..477ff29dbd 100644
--- a/railties/guides/source/debugging_rails_applications.textile
+++ b/railties/guides/source/debugging_rails_applications.textile
@@ -308,6 +308,41 @@ If you repeat the +list+ command, this time using just +l+, the next ten lines o
And so on until the end of the current file. When the end of file is reached, the +list+ command will start again from the beginning of the file and continue again up to the end, treating the file as a circular buffer.
+On the other hand, to see the previous ten lines you should type +list-+ (or +l-+)
+
+<shell>
+(rdb:7) l-
+[1, 10] in /PathToProject/posts_controller.rb
+ 1 class PostsController < ApplicationController
+ 2 # GET /posts
+ 3 # GET /posts.xml
+ 4 def index
+ 5 debugger
+ 6 @posts = Post.all
+ 7
+ 8 respond_to do |format|
+ 9 format.html # index.html.erb
+ 10 format.xml { render :xml => @posts }
+</shell>
+
+This way you can move inside the file, being able to see the code above and over the line you added the +debugger+.
+Finally, to see where you are in the code again you can type +list=+
+
+<shell>
+(rdb:7) list=
+[1, 10] in /PathToProject/posts_controller.rb
+ 1 class PostsController < ApplicationController
+ 2 # GET /posts
+ 3 # GET /posts.xml
+ 4 def index
+ 5 debugger
+=> 6 @posts = Post.all
+ 7
+ 8 respond_to do |format|
+ 9 format.html # index.html.erb
+ 10 format.xml { render :xml => @posts }
+</shell>
+
h4. The Context
When you start debugging your application, you will be placed in different contexts as you go through the different parts of the stack.
diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile
index 1f21c27ae6..a63245acec 100644
--- a/railties/guides/source/form_helpers.textile
+++ b/railties/guides/source/form_helpers.textile
@@ -258,7 +258,7 @@ The name passed to +form_for+ controls the key used in +params+ to access the fo
The helper methods called on the form builder are identical to the model object helpers except that it is not necessary to specify which object is being edited since this is already managed by the form builder.
-You can create a similar binding without actually creating +&lt;form&gt;+ tags with the +fields_for+ helper. This is useful for editing additional model objects with the same form. For example if you had a Person model with an associated ContactDetail model you could create a form for creating both like so:
+You can create a similar binding without actually creating +&lt;form&gt;+ tags with the +fields_for+ helper. This is useful for editing additional model objects with the same form. For example if you had a Person model with an associated ContactDetail model you could create a form for creating both like so:
<erb>
<%= form_for @person, :url => { :action => "create" } do |person_form| %>
@@ -438,7 +438,7 @@ As with other helpers, if you were to use the +select+ helper on a form builder
<%= f.select(:city_id, ...) %>
</erb>
-WARNING: If you are using +select+ (or similar helpers such as +collection_select+, +select_tag+) to set a +belongs_to+ association you must pass the name of the foreign key (in the example above +city_id+), not the name of association itself. If you specify +city+ instead of +city_id+ Active Record will raise an error along the lines of <tt> ActiveRecord::AssociationTypeMismatch: City(#17815740) expected, got String(#1138750) </tt> when you pass the +params+ hash to +Person.new+ or +update_attributes+. Another way of looking at this is that form helpers only edit attributes. You should also be aware of the potential security ramifications of allowing users to edit foreign keys directly. You may wish to consider the use of +attr_protected+ and +attr_accessible+. For further details on this, see the "Ruby On Rails Security Guide":security.html#_mass_assignment.
+WARNING: If you are using +select+ (or similar helpers such as +collection_select+, +select_tag+) to set a +belongs_to+ association you must pass the name of the foreign key (in the example above +city_id+), not the name of association itself. If you specify +city+ instead of +city_id+ Active Record will raise an error along the lines of <tt> ActiveRecord::AssociationTypeMismatch: City(#17815740) expected, got String(#1138750) </tt> when you pass the +params+ hash to +Person.new+ or +update_attributes+. Another way of looking at this is that form helpers only edit attributes. You should also be aware of the potential security ramifications of allowing users to edit foreign keys directly. You may wish to consider the use of +attr_protected+ and +attr_accessible+. For further details on this, see the "Ruby On Rails Security Guide":security.html#_mass_assignment.
h4. Option Tags from a Collection of Arbitrary Objects
@@ -513,7 +513,7 @@ The +:prefix+ option is the key used to retrieve the hash of date components fro
h4(#select-model-object-helpers). Model Object Helpers
+select_date+ does not work well with forms that update or create Active Record objects as Active Record expects each element of the +params+ hash to correspond to one attribute.
-The model object helpers for dates and times submit parameters with special names, when Active Record sees parameters with such names it knows they must be combined with the other parameters and given to a constructor appropriate to the column type. For example:
+The model object helpers for dates and times submit parameters with special names, when Active Record sees parameters with such names it knows they must be combined with the other parameters and given to a constructor appropriate to the column type. For example:
<erb>
<%= date_select :person, :birth_date %>
diff --git a/railties/guides/source/generators.textile b/railties/guides/source/generators.textile
index cd8ac3d6fd..ac709968d9 100644
--- a/railties/guides/source/generators.textile
+++ b/railties/guides/source/generators.textile
@@ -190,7 +190,7 @@ $ rails generate scaffold User name:string
invoke test_unit
create test/unit/helpers/users_helper_test.rb
invoke stylesheets
- create app/assets/stylesheets/scaffold.css.scss
+ create app/assets/stylesheets/scaffold.css
</shell>
Looking at this output, it's easy to understand how generators work in Rails 3.0 and above. The scaffold generator doesn't actually generate anything, it just invokes others to do the work. This allows us to add/replace/remove any of those invocations. For instance, the scaffold generator invokes the scaffold_controller generator, which invokes erb, test_unit and helper generators. Since each generator has a single responsibility, they are easy to reuse, avoiding code duplication.
@@ -383,7 +383,7 @@ if yes?("Would you like to install Devise?")
end
</ruby>
-In the above template we specify that the application relies on the +rspec-rails+ and +cucumber-rails+ gem so these two will be added to the +test+ group in the +Gemfile+. Then we pose a question to the user about whether or not they would like to install Devise. If the user replies "y" or "yes" to this question, then the template will add Devise to the +Gemfile+ outside of any group and then runs the +devise:install+ generator. This template then takes the users input and runs the +devise+ generator, with the user's answer from the last question being passed to this generator.
+In the above template we specify that the application relies on the +rspec-rails+ and +cucumber-rails+ gem so these two will be added to the +test+ group in the +Gemfile+. Then we pose a question to the user about whether or not they would like to install Devise. If the user replies "y" or "yes" to this question, then the template will add Devise to the +Gemfile+ outside of any group and then runs the +devise:install+ generator. This template then takes the users input and runs the +devise+ generator, with the user's answer from the last question being passed to this generator.
Imagine that this template was in a file called +template.rb+. We can use it to modify the outcome of the +rails new+ command by using the +-m+ option and passing in the filename:
diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile
index 3f9bd2b6da..366df9cd84 100644
--- a/railties/guides/source/getting_started.textile
+++ b/railties/guides/source/getting_started.textile
@@ -22,7 +22,7 @@ TIP: Note that Ruby 1.8.7 p248 and p249 have marshaling bugs that crash Rails 3.
* The "RubyGems":http://rubyforge.org/frs/?group_id=126 packaging system
* A working installation of the "SQLite3 Database":http://www.sqlite.org
-Rails is a web application framework running on the Ruby programming language. If you have no prior experience with Ruby, you will find a very steep learning curve diving straight into Rails. There are some good free resources on the internet for learning Ruby, including:
+Rails is a web application framework running on the Ruby programming language. If you have no prior experience with Ruby, you will find a very steep learning curve diving straight into Rails. There are some good free resources on the internet for learning Ruby, including:
* "Mr. Neighborly's Humble Little Ruby Book":http://www.humblelittlerubybook.com
* "Programming Ruby":http://www.ruby-doc.org/docs/ProgrammingRuby/
@@ -78,7 +78,7 @@ Rails ships as many individual components.
h5. Action Pack
-Action Pack is a single gem that contains Action Controller, Action View and Action Dispatch. The "VC" part of "MVC".
+Action Pack is a single gem that contains Action Controller, Action View and Action Dispatch. The "VC" part of "MVC".
h5. Action Controller
@@ -98,7 +98,7 @@ Action Mailer is a framework for building e-mail services. You can use Action Ma
h5. Active Model
-Active Model provides a defined interface between the Action Pack gem services and Object Relationship Mapping gems such as Active Record. Active Model allows Rails to utilize other ORM frameworks in place of Active Record if your application needs this.
+Active Model provides a defined interface between the Action Pack gem services and Object Relationship Mapping gems such as Active Record. Active Model allows Rails to utilize other ORM frameworks in place of Active Record if your application needs this.
h5. Active Record
@@ -153,7 +153,7 @@ TIP. If you're working on Windows, you can quickly install Ruby and Rails with "
h4. Creating the Blog Application
-The best way to use this guide is to follow each step as it happens, no code or step needed to make this example application has been left out, so you can literally follow along step by step. If you need to see the completed code, you can download it from "Getting Started Code":https://github.com/mikel/getting-started-code.
+The best way to use this guide is to follow each step as it happens, no code or step needed to make this example application has been left out, so you can literally follow along step by step. If you need to see the completed code, you can download it from "Getting Started Code":https://github.com/mikel/getting-started-code.
To begin, open a terminal, navigate to a folder where you have rights to create files, and type:
@@ -184,7 +184,7 @@ In any case, Rails will create a folder in your working directory called <tt>blo
|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. This is where your images, JavaScript files, stylesheets (CSS), and other static files go.|
|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|
@@ -290,7 +290,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
@@ -310,7 +310,7 @@ Rails will create several files for you, including +app/views/home/index.html.er
h4. Setting the Application Home Page
-Now that we have made the controller and view, we need to tell Rails when we want "Hello Rails" to show up. In our case, we want it to show up when we navigate to the root URL of our site, "http://localhost:3000":http://localhost:3000, instead of the "Welcome Aboard" smoke test.
+Now that we have made the controller and view, we need to tell Rails when we want "Hello Rails" to show up. In our case, we want it to show up when we navigate to the root URL of our site, "http://localhost:3000":http://localhost:3000, instead of the "Welcome Aboard" smoke test.
The first step to doing this is to delete the default page from your application:
@@ -394,7 +394,7 @@ class CreatePosts < ActiveRecord::Migration
end
</ruby>
-The above migration creates two methods, +up+, called when you run this migration into the database, and +down+ in case you need to reverse the changes made by this migration at a later date. The +up+ command in this case creates a +posts+ table with two string columns and a text column. It also creates two timestamp fields to track record creation and updating. More information about Rails migrations can be found in the "Rails Database Migrations":migrations.html guide.
+The above migration creates two methods, +up+, called when you run this migration into the database, and +down+ in case you need to reverse the changes made by this migration at a later date. The +up+ command in this case creates a +posts+ table with two string columns and a text column. It also creates two timestamp fields to track record creation and updating. More information about Rails migrations can be found in the "Rails Database Migrations":migrations.html guide.
At this point, you can use a rake command to run the migration:
@@ -548,7 +548,7 @@ This view iterates over the contents of the +@posts+ array to display content an
* +link_to+ builds a hyperlink to a particular destination
* +edit_post_path+ and +new_post_path+ are helpers that Rails provides as part of RESTful routing. You'll see a variety of these helpers for the different actions that the controller includes.
-NOTE. In previous versions of Rails, you had to use +&lt;%=h post.name %&gt;+ so that any HTML would be escaped before being inserted into the page. In Rails 3.0, this is now the default. To get unescaped HTML, you now use +&lt;%= raw post.name %&gt;+.
+NOTE. In previous versions of Rails, you had to use +&lt;%=h post.name %&gt;+ so that any HTML would be escaped before being inserted into the page. In Rails 3.0, this is now the default. To get unescaped HTML, you now use +&lt;%= raw post.name %&gt;+.
TIP: For more details on the rendering process, see "Layouts and Rendering in Rails":layouts_and_rendering.html.
@@ -600,7 +600,7 @@ The +new.html.erb+ view displays this empty Post to the user:
<%= link_to 'Back', posts_path %>
</erb>
-The +&lt;%= render 'form' %&gt;+ line is our first introduction to _partials_ in Rails. A partial is a snippet of HTML and Ruby code that can be reused in multiple locations. In this case, the form used to make a new post, is basically identical to a form used to edit a post, both have text fields for the name and title and a text area for the content with a button to make a new post or update the existing post.
+The +&lt;%= render 'form' %&gt;+ line is our first introduction to _partials_ in Rails. A partial is a snippet of HTML and Ruby code that can be reused in multiple locations. In this case, the form used to make a new post, is basically identical to a form used to edit a post, both have text fields for the name and title and a text area for the content with a button to make a new post or update the existing post.
If you take a look at +views/posts/_form.html.erb+ file, you will see the following:
@@ -873,7 +873,7 @@ TIP: For more information on Active Record associations, see the "Active Record
h4. Adding a Route for Comments
-As with the +home+ controller, we will need to add a route so that Rails knows where we would like to navigate to see +comments+. Open up the +config/routes.rb+ file again, you will see an entry that was added automatically for +posts+ near the top by the scaffold generator, +resources :posts+, edit it as follows:
+As with the +home+ controller, we will need to add a route so that Rails knows where we would like to navigate to see +comments+. Open up the +config/routes.rb+ file again, you will see an entry that was added automatically for +posts+ near the top by the scaffold generator, +resources :posts+, edit it as follows:
<ruby>
resources :posts do
@@ -901,7 +901,7 @@ This creates four files and one empty directory:
* +test/unit/helpers/comments_helper_test.rb+ - The unit tests for the helper
* +app/views/comments/+ - Views of the controller are stored here
-Like with any blog, our readers will create their comments directly after reading the post, and once they have added their comment, will be sent back to the post show page to see their comment now listed. Due to this, our +CommentsController+ is there to provide a method to create comments and delete SPAM comments when they arrive.
+Like with any blog, our readers will create their comments directly after reading the post, and once they have added their comment, will be sent back to the post show page to see their comment now listed. Due to this, our +CommentsController+ is there to provide a method to create comments and delete SPAM comments when they arrive.
So first, we'll wire up the Post show template (+/app/views/posts/show.html.erb+) to let us make a new comment:
@@ -1078,7 +1078,7 @@ Then in the +app/views/posts/show.html.erb+ you can change it to look like the f
<%= link_to 'Back to Posts', posts_path %> |
</erb>
-This will now render the partial in +app/views/comments/_comment.html.erb+ once for each comment that is in the +@post.comments+ collection. As the +render+ method iterates over the <tt>@post.comments</tt> collection, it assigns each comment to a local variable named the same as the partial, in this case +comment+ which is then available in the partial for us to show.
+This will now render the partial in +app/views/comments/_comment.html.erb+ once for each comment that is in the +@post.comments+ collection. As the +render+ method iterates over the <tt>@post.comments</tt> collection, it assigns each comment to a local variable named the same as the partial, in this case +comment+ which is then available in the partial for us to show.
h4. Rendering a Partial Form
@@ -1138,7 +1138,7 @@ The +@post+ object is available to any partials rendered in the view because we
h3. Deleting Comments
-Another important feature on a blog is being able to delete SPAM comments. To do this, we need to implement a link of some sort in the view and a +DELETE+ action in the +CommentsController+.
+Another important feature on a blog is being able to delete SPAM comments. To do this, we need to implement a link of some sort in the view and a +DELETE+ action in the +CommentsController+.
So first, let's add the delete link in the +app/views/comments/_comment.html.erb+ partial:
@@ -1312,7 +1312,7 @@ Note that we have changed the +f+ in +form_for(@post) do |f|+ to +post_form+ to
This example shows another option of the render helper, being able to pass in local variables, in this case, we want the local variable +form+ in the partial to refer to the +post_form+ object.
-We also add a <tt>@post.tags.build</tt> at the top of this form, this is to make sure there is a new tag ready to have it's name filled in by the user. If you do not build the new tag, then the form will not appear as there is no new Tag object ready to create.
+We also add a <tt>@post.tags.build</tt> at the top of this form, this is to make sure there is a new tag ready to have it's name filled in by the user. If you do not build the new tag, then the form will not appear as there is no new Tag object ready to create.
Now create the folder <tt>app/views/tags</tt> and make a file in there called <tt>_form.html.erb</tt> which contains the form for the tag:
@@ -1373,7 +1373,7 @@ However, that method call <tt>@post.tags.map { |t| t.name }.join(", ")</tt> is a
h3. View Helpers
-View Helpers live in <tt>app/helpers</tt> and provide small snippets of reusable code for views. In our case, we want a method that strings a bunch of objects together using their name attribute and joining them with a comma. As this is for the Post show template, we put it in the PostsHelper.
+View Helpers live in <tt>app/helpers</tt> and provide small snippets of reusable code for views. In our case, we want a method that strings a bunch of objects together using their name attribute and joining them with a comma. As this is for the Post show template, we put it in the PostsHelper.
Open up <tt>app/helpers/posts_helper.rb</tt> and add the following:
diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile
index 3e7e396e8d..608643b3d3 100644
--- a/railties/guides/source/i18n.textile
+++ b/railties/guides/source/i18n.textile
@@ -91,7 +91,7 @@ This means, that in the +:en+ locale, the key _hello_ will map to the _Hello wor
The I18n library will use *English* as a *default locale*, i.e. if you don't set a different locale, +:en+ will be used for looking up translations.
-NOTE: The i18n library takes a *pragmatic approach* to locale keys (after "some discussion":http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like +:en+, +:pl+, not the _region_ part, like +:en-US+ or +:en-UK+, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as +:cz+, +:th+ or +:es+ (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the +:en-US+ locale you would have $ as a currency symbol, while in +:en-UK+, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a +:en-UK+ dictionary. Various "Rails I18n plugins":http://rails-i18n.org/wiki such as "Globalize2":https://github.com/joshmh/globalize2/tree/master may help you implement it.
+NOTE: The i18n library takes a *pragmatic approach* to locale keys (after "some discussion":http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like +:en+, +:pl+, not the _region_ part, like +:en-US+ or +:en-UK+, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as +:cz+, +:th+ or +:es+ (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the +:en-US+ locale you would have $ as a currency symbol, while in +:en-UK+, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a +:en-UK+ dictionary. Various "Rails I18n plugins":http://rails-i18n.org/wiki such as "Globalize2":https://github.com/joshmh/globalize2/tree/master may help you implement it.
The *translations load path* (+I18n.load_path+) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you.
@@ -133,9 +133,9 @@ The _setting part_ is easy. You can set the locale in a +before_filter+ in the +
<ruby>
before_filter :set_locale
+
def set_locale
- # if params[:locale] is nil then I18n.default_locale will be used
- I18n.locale = params[:locale]
+ I18n.locale = params[:locale] || I18n.default_locale
end
</ruby>
@@ -158,7 +158,7 @@ You can implement it like this in your +ApplicationController+:
before_filter :set_locale
def set_locale
- I18n.locale = extract_locale_from_tld
+ I18n.locale = extract_locale_from_tld || I18n.default_locale
end
# Get locale from top-level domain or return nil if such locale is not available
@@ -182,7 +182,7 @@ We can also set the locale from the _subdomain_ in a very similar way:
# in your /etc/hosts file to try this out locally
def extract_locale_from_subdomain
parsed_locale = request.subdomains.first
- I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale : nil
+ I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale : nil
end
</ruby>
@@ -441,7 +441,7 @@ Do check the "Rails i18n Wiki":http://rails-i18n.org/wiki for list of tools avai
h3. Overview of the I18n API Features
-You should have good understanding of using the i18n library now, knowing all necessary aspects of internationalizing a basic Rails application. In the following chapters, we'll cover it's features in more depth.
+You should have good understanding of using the i18n library now, knowing all necessary aspects of internationalizing a basic Rails application. In the following chapters, we'll cover it's features in more depth.
Covered are features like these:
@@ -520,7 +520,7 @@ I18n.t 'activerecord.errors.messages'
h5. "Lazy" Lookup
-Rails 2.3 implements a convenient way to look up the locale inside _views_. When you have the following dictionary:
+Rails implements a convenient way to look up the locale inside _views_. When you have the following dictionary:
<yaml>
es:
@@ -863,7 +863,7 @@ If you find anything missing or wrong in this guide, please file a ticket on our
h3. Contributing to Rails I18n
-I18n support in Ruby on Rails was introduced in the release 2.2 and is still evolving. The project follows the good Ruby on Rails development tradition of evolving solutions in plugins and real applications first, and only then cherry-picking the best-of-bread of most widely useful features for inclusion in the core.
+I18n support in Ruby on Rails was introduced in the release 2.2 and is still evolving. The project follows the good Ruby on Rails development tradition of evolving solutions in plugins and real applications first, and only then cherry-picking the best-of-breed of most widely useful features for inclusion in the core.
Thus we encourage everybody to experiment with new ideas and features in plugins or other libraries and make them available to the community. (Don't forget to announce your work on our "mailing list":http://groups.google.com/group/rails-i18n!)
diff --git a/railties/guides/source/index.html.erb b/railties/guides/source/index.html.erb
index af46beee56..b48488d8a2 100644
--- a/railties/guides/source/index.html.erb
+++ b/railties/guides/source/index.html.erb
@@ -17,7 +17,7 @@ Ruby on Rails Guides
<% else %>
<p>
These are the new guides for Rails 3. The guides for Rails 2.3 are still available
- at <a href="http://guides.rubyonrails.org/v2.3.8/">http://guides.rubyonrails.org/v2.3.8/</a>.
+ at <a href="http://guides.rubyonrails.org/v2.3.11/">http://guides.rubyonrails.org/v2.3.11/</a>.
</p>
<% end %>
<p>
diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile
index 7c01f01b24..638830cd83 100644
--- a/railties/guides/source/initialization.textile
+++ b/railties/guides/source/initialization.textile
@@ -468,7 +468,7 @@ h4. +config/application.rb+
This file requires +config/boot.rb+, but only if it hasn't been required before, which would be the case in +rails server+ but *wouldn't* be the case with Passenger.
-Then the fun begins!
+Then the fun begins!
h3. Loading Rails
@@ -592,7 +592,11 @@ This file defines the behavior of the +ActiveSupport::Deprecation+ module, setti
h4. +activesupport/lib/active_support/notifications.rb+
-TODO: document +ActiveSupport::Notifications+.
+This file defines the +ActiveSupport::Notifications+ module. Notifications provides an instrumentation API for Ruby, shipping with a queue implementation that consumes and publish events to log subscribers in a thread.
+
+The "API documentation":http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html for +ActiveSupport::Notifications+ explains the usage of this module, including the methods that it defines.
+
+The file required in +active_support/notifications.rb+ is +active_support/core_ext/module/delegation+ which is documented in the "Active Support Core Extensions Guide":http://guides.rubyonrails.org/active_support_core_extensions.html#method-delegation.
h4. +activesupport/core_ext/array/wrap+
@@ -660,7 +664,7 @@ The +active_support/inflector/methods+ file has already been required by +active
h4. +activesupport/lib/active_support/inflector/inflections.rb+
-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".
+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".
h4. +activesupport/lib/active_support/inflector/transliterate.rb+
@@ -694,7 +698,7 @@ h4. Back to +railties/lib/rails/plugin.rb+
The next file required in this is a core extension from Active Support called +array/conversions+ which is covered in "this section":http://guides.rubyonrails.org/active_support_core_extensions.html#array-conversions of the Active Support Core Extensions Guide.
-Once that file has finished loading, the +Rails::Plugin+ class is defined.
+Once that file has finished loading, the +Rails::Plugin+ class is defined.
h4. Back to +railties/lib/rails/application.rb+
@@ -704,7 +708,7 @@ Once this file's done then we go back to the +railties/lib/rails.rb+ file, which
h4. +railties/lib/rails/version.rb+
-Much like +active_support/version+, this file defines the +VERSION+ constant which has a +STRING+ constant on it which returns the current version of Rails.
+Much like +active_support/version+, this file defines the +VERSION+ constant which has a +STRING+ constant on it which returns the current version of Rails.
Once this file has finished loading we go back to +railties/lib/rails.rb+ which then requires +active_support/railtie.rb+.
@@ -922,7 +926,7 @@ This file defines the +ActionDispatch::Railtie+ class, but not before requiring
h4. +activesupport/lib/action_dispatch.rb+
-This file attempts to locate the +active_support+ and +active_model+ libraries by looking a couple of directories back from the current file and then adds the +active_support+ and +active_model+ +lib+ directories to the load path, but only if they aren't already, which they are.
+This file attempts to locate the +active_support+ and +active_model+ libraries by looking a couple of directories back from the current file and then adds the +active_support+ and +active_model+ +lib+ directories to the load path, but only if they aren't already, which they are.
<ruby>
activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
@@ -1005,7 +1009,7 @@ The loading of this file finishes the loading of +active_model+ and so we go bac
h4. Back to +activesupport/lib/action_dispatch.rb+
-The remainder of this file requires the +rack+ file from the Rack gem which defines the +Rack+ module. After +rack+, there's autoloads defined for the +Rack+, +ActionDispatch+, +ActionDispatch::Http+, +ActionDispatch::Session+. A new method called +autoload_under+ is used here, and this simply prefixes the files where the modules are autoloaded from with the path specified. For example here:
+The remainder of this file requires the +rack+ file from the Rack gem which defines the +Rack+ module. After +rack+, there's autoloads defined for the +Rack+, +ActionDispatch+, +ActionDispatch::Http+, +ActionDispatch::Session+. A new method called +autoload_under+ is used here, and this simply prefixes the files where the modules are autoloaded from with the path specified. For example here:
<ruby>
autoload_under 'testing' do
@@ -1108,4 +1112,4 @@ However the require after these is to a file that hasn't yet been loaded, +actio
h4. +actionpack/lib/action_view.rb+
-+action_view.rb+
++action_view.rb+
diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile
index 8dab578e6b..620df970dc 100644
--- a/railties/guides/source/layouts_and_rendering.textile
+++ b/railties/guides/source/layouts_and_rendering.textile
@@ -394,7 +394,7 @@ end
Now, if the current user is a special user, they'll get a special layout when viewing a product. You can even use an inline method to determine the layout:
-You can also decide the layout by passing a Proc object, the block you give the Proc will be given the +controller+ instance, so you can make decisions based on the current request. For example:
+You can also decide the layout by passing a Proc object, the block you give the Proc will be given the +controller+ instance, so you can make decisions based on the current request. For example:
<ruby>
class ProductsController < ApplicationController
@@ -572,7 +572,7 @@ With this code, the browser will make a fresh request for the index page, the co
The only downside to this code, is that it requires a round trip to the browser, the browser requested the show action with +/books/1+ and the controller finds that there are no books, so the controller sends out a 302 redirect response to the browser telling it to go to +/books/+, the browser complies and sends a new request back to the controller asking now for the +index+ action, the controller then gets all the books in the database and renders the index template, sending it back down to the browser which then shows it on your screen.
-While in a small app, this added latency might not be a problem, it is something to think about when speed of response is of the essence. One way to handle this double request (though a contrived example) could be:
+While in a small app, this added latency might not be a problem, it is something to think about when speed of response is of the essence. One way to handle this double request (though a contrived example) could be:
<ruby>
def index
@@ -860,7 +860,7 @@ Produces
<video src="/videos/movie.ogg" />
</erb>
-Like an +image_tag+ you can supply a path, either absolute, or relative to the +public/videos+ directory. Additionally you can specify the +:size => "#{width}x#{height}"+ option just like an +image_tag+. Video tags can also have any of the HTML options specified at the end (+id+, +class+ et al).
+Like an +image_tag+ you can supply a path, either absolute, or relative to the +public/videos+ directory. Additionally you can specify the +:size => "#{width}x#{height}"+ option just like an +image_tag+. Video tags can also have any of the HTML options specified at the end (+id+, +class+ et al).
The video tag also supports all of the +&lt;video&gt;+ HTML options through the HTML options hash, including:
@@ -1133,7 +1133,7 @@ You can also pass in arbitrary local variables to any partial you are rendering
Would render a partial +_products.html.erb+ once for each instance of +product+ in the +@products+ instance variable passing the instance to the partial as a local variable called +item+ and to each partial, make the local variable +title+ available with the value +Products Page+.
-TIP: Rails also makes a counter variable available within a partial called by the collection, named after the member of the collection followed by +_counter+. For example, if you're rendering +@products+, within the partial you can refer to +product_counter+ to tell you how many times the partial has been rendered. This does not work in conjunction with the +:as => :value+ option.
+TIP: Rails also makes a counter variable available within a partial called by the collection, named after the member of the collection followed by +_counter+. For example, if you're rendering +@products+, within the partial you can refer to +product_counter+ to tell you how many times the partial has been rendered. This does not work in conjunction with the +:as => :value+ option.
You can also specify a second partial to be rendered between instances of the main partial by using the +:spacer_template+ option:
diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile
index 57e6bcd123..bf5d4d3e4d 100644
--- a/railties/guides/source/migrations.textile
+++ b/railties/guides/source/migrations.textile
@@ -284,7 +284,7 @@ change_table :products do |t|
t.rename :upccode, :upc_code
end
</ruby>
-removes the +description+ and +name+ columns, creates a +part_number+ column and adds an index on it. Finally it renames the +upccode+ column. This is the same as doing
+removes the +description+ and +name+ columns, creates a +part_number+ column and adds an index on it. Finally it renames the +upccode+ column. This is the same as doing
<ruby>
remove_column :products, :description
@@ -335,7 +335,7 @@ NOTE: The +references+ helper does not actually create foreign key constraints f
If the helpers provided by Active Record aren't enough you can use the +execute+ function to execute arbitrary SQL.
-For more details and examples of individual methods check the API documentation, in particular the documentation for "<tt>ActiveRecord::ConnectionAdapters::SchemaStatements</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html (which provides the methods available in the +up+ and +down+ methods), "<tt>ActiveRecord::ConnectionAdapters::TableDefinition</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html (which provides the methods available on the object yielded by +create_table+) and "<tt>ActiveRecord::ConnectionAdapters::Table</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html (which provides the methods available on the object yielded by +change_table+).
+For more details and examples of individual methods check the API documentation, in particular the documentation for "<tt>ActiveRecord::ConnectionAdapters::SchemaStatements</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html (which provides the methods available in the +up+ and +down+ methods), "<tt>ActiveRecord::ConnectionAdapters::TableDefinition</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html (which provides the methods available on the object yielded by +create_table+) and "<tt>ActiveRecord::ConnectionAdapters::Table</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html (which provides the methods available on the object yielded by +change_table+).
h4. Writing Your +down+ Method
diff --git a/railties/guides/source/plugins.textile b/railties/guides/source/plugins.textile
index 2d9821e627..d486e8ade3 100644
--- a/railties/guides/source/plugins.textile
+++ b/railties/guides/source/plugins.textile
@@ -17,8 +17,8 @@ This guide describes how to build a test-driven plugin that will:
* Add methods to ActiveRecord::Base in the tradition of the 'acts_as' plugins
* Give you information about where to put generators in your plugin.
-For the purpose of this guide pretend for a moment that you are an avid bird watcher.
-Your favorite bird is the Yaffle, and you want to create a plugin that allows other developers to share in the Yaffle
+For the purpose of this guide pretend for a moment that you are an avid bird watcher.
+Your favorite bird is the Yaffle, and you want to create a plugin that allows other developers to share in the Yaffle
goodness.
endprologue.
@@ -27,21 +27,21 @@ h3. Setup
h4. Generating the Plugin Skeleton
-Rails currently ships with a generator to generate a plugin within a Rails application. Help text is available that will explain
+Rails currently ships with a generator to generate a plugin within a Rails application. Help text is available that will explain
how this generator works.
<shell>
$ rails generate plugin --help
</shell>
-This generator places the plugin into the vendor/plugins directory.
+This generator places the plugin into the vendor/plugins directory.
-Vendored plugins are useful for quickly prototyping your plugin but current thinking in the Rails community is shifting towards
+Vendored plugins are useful for quickly prototyping your plugin but current thinking in the Rails community is shifting towards
packaging plugins as gems, especially with the inclusion of Bundler as the Rails dependency manager.
Packaging a plugin as a gem may be overkill for any plugins that will not be shared across projects but doing so from the start makes it easier to share the plugin going forward without adding too much additional overhead during development.
Rails 3.1 will ship with a plugin generator that will default to setting up a plugin
-as a gem. This tutorial will begin to bridge that gap by demonstrating how to create a gem based plugin using the
+as a gem. This tutorial will begin to bridge that gap by demonstrating how to create a gem based plugin using the
"Enginex gem":http://www.github.com/josevalim/enginex.
<shell>
@@ -69,7 +69,7 @@ h3. Extending Core Classes
This section will explain how to add a method to String that will be available anywhere in your rails application.
-In this example you will add a method to String named +to_squawk+. To begin, create a new test file with a few assertions:
+In this example you will add a method to String named +to_squawk+. To begin, create a new test file with a few assertions:
<ruby>
# yaffle/test/core_ext_test.rb
@@ -83,7 +83,7 @@ class CoreExtTest < Test::Unit::TestCase
end
</ruby>
-Run +rake+ to run the test. This test should fail because we haven't implemented the +to_squak+ method:
+Run +rake+ to run the test. This test should fail because we haven't implemented the +to_squak+ method:
<shell>
1) Error:
@@ -133,7 +133,7 @@ $ rails console
h3. Add an "acts_as" Method to Active Record
-A common pattern in plugins is to add a method called 'acts_as_something' to models. In this case, you
+A common pattern in plugins is to add a method called 'acts_as_something' to models. In this case, you
want to write a method called 'acts_as_yaffle' that adds a 'squawk' method to your Active Record models.
To begin, set up your files so that you have:
@@ -169,9 +169,9 @@ end
h4. Add a Class Method
-This plugin will expect that you've added a method to your model named 'last_squawk'. However, the
-plugin users might have already defined a method on their model named 'last_squawk' that they use
-for something else. This plugin will allow the name to be changed by adding a class method called 'yaffle_text_field'.
+This plugin will expect that you've added a method to your model named 'last_squawk'. However, the
+plugin users might have already defined a method on their model named 'last_squawk' that they use
+for something else. This plugin will allow the name to be changed by adding a class method called 'yaffle_text_field'.
To start out, write a failing test that shows the behavior you'd like:
@@ -210,7 +210,7 @@ When you run +rake+, you should see the following:
</shell>
This tells us that we don't have the necessary models (Hickwall and Wickwall) that we are trying to test.
-We can easily generate these models in our "dummy" Rails application by running the following commands from the
+We can easily generate these models in our "dummy" Rails application by running the following commands from the
test/dummy directory:
<shell>
@@ -220,7 +220,7 @@ $ rails generate model Wickwall last_squak:string last_tweet:string
</shell>
Now you can create the necessary database tables in your testing database by navigating to your dummy app
-and migrating the database. First
+and migrating the database. First
<shell>
$ cd test/dummy
@@ -319,7 +319,7 @@ When you run +rake+ you should see the tests all pass:
h4. Add an Instance Method
-This plugin will add a method named 'squawk' to any Active Record objects that call 'acts_as_yaffle'. The 'squawk'
+This plugin will add a method named 'squawk' to any Active Record objects that call 'acts_as_yaffle'. The 'squawk'
method will simply set the value of one of the fields in the database.
To start out, write a failing test that shows the behavior you'd like:
@@ -352,7 +352,7 @@ class ActsAsYaffleTest < Test::Unit::TestCase
end
</ruby>
-Run the test to make sure the last two tests fail the an error that contains "NoMethodError: undefined method `squawk'",
+Run the test to make sure the last two tests fail the an error that contains "NoMethodError: undefined method `squawk'",
then update 'acts_as_yaffle.rb' to look like this:
<ruby>
@@ -387,18 +387,18 @@ Run +rake+ one final time and you should see:
7 tests, 7 assertions, 0 failures, 0 errors, 0 skips
</shell>
-NOTE: The use of +write_attribute+ to write to the field in model is just one example of how a plugin can
-interact with the model, and will not always be the right method to use. For example, you could also
+NOTE: The use of +write_attribute+ to write to the field in model is just one example of how a plugin can
+interact with the model, and will not always be the right method to use. For example, you could also
use +send("#{self.class.yaffle_text_field}=", string.to_squawk)+.
h3. Generators
-Generators can be included in your gem simply by creating them in a lib/generators directory of your plugin. More information about
+Generators can be included in your gem simply by creating them in a lib/generators directory of your plugin. More information about
the creation of generators can be found in the "Generators Guide":generators.html
h3. Publishing your Gem
-Gem plugins in progress can be easily be shared from any Git repository. To share the Yaffle gem with others, simply
+Gem plugins in progress can be easily be shared from any Git repository. To share the Yaffle gem with others, simply
commit the code to a Git repository (like Github) and add a line to the Gemfile of the any application:
<ruby>
@@ -412,7 +412,7 @@ For more information about publishing gems to RubyGems, see: "http://blog.thepet
h3. Non-Gem Plugins
-Non-gem plugins are useful for functionality that won't be shared with another project. Keeping your custom functionality in the
+Non-gem plugins are useful for functionality that won't be shared with another project. Keeping your custom functionality in the
vendor/plugins directory un-clutters the rest of the application.
Move the directory that you created for the gem based plugin into the vendor/plugins directory of a generated Rails application, create a vendor/plugins/yaffle/init.rb file that contains "require 'yaffle'" and everything will still work.
@@ -423,7 +423,7 @@ Move the directory that you created for the gem based plugin into the vendor/plu
require 'yaffle'
</ruby>
-You can test this by changing to the Rails application that you added the plugin to and starting a rails console. Once in the
+You can test this by changing to the Rails application that you added the plugin to and starting a rails console. Once in the
console we can check to see if the String has an instance method of to_squawk.
<shell>
$ cd my_app
@@ -435,7 +435,7 @@ You can also remove the .gemspec, Gemfile and Gemfile.lock files as they will no
h3. RDoc Documentation
-Once your plugin is stable and you are ready to deploy do everyone else a favor and document it! Luckily, writing documentation for your plugin is easy.
+Once your plugin is stable and you are ready to deploy do everyone else a favor and document it! Luckily, writing documentation for your plugin is easy.
The first step is to update the README file with detailed information about how to use your plugin. A few key things to include are:
diff --git a/railties/guides/source/rails_application_templates.textile b/railties/guides/source/rails_application_templates.textile
index 8e51f9e23b..388d8eea3e 100644
--- a/railties/guides/source/rails_application_templates.textile
+++ b/railties/guides/source/rails_application_templates.textile
@@ -11,19 +11,19 @@ endprologue.
h3. Usage
-To apply a template, you need to provide the Rails generator with the location of the template you wish to apply, using -m option :
+To apply a template, you need to provide the Rails generator with the location of the template you wish to apply, using -m option:
<shell>
$ rails new blog -m ~/template.rb
</shell>
-It's also possible to apply a template using a URL :
+It's also possible to apply a template using a URL:
<shell>
$ rails new blog -m https://gist.github.com/755496.txt
</shell>
-Alternatively, you can use the rake task +rails:template+ to apply a template to an existing Rails application :
+Alternatively, you can use the rake task +rails:template+ to apply a template to an existing Rails application:
<shell>
$ rake rails:template LOCATION=~/template.rb
@@ -31,7 +31,7 @@ $ rake rails:template LOCATION=~/template.rb
h3. Template API
-Rails templates API is very self explanatory and easy to understand. Here's an example of a typical Rails template :
+Rails templates API is very self explanatory and easy to understand. Here's an example of a typical Rails template:
<ruby>
# template.rb
@@ -45,20 +45,20 @@ git :add => "."
git :commit => "-a -m 'Initial commit'"
</ruby>
-The following sections outlines the primary methods provided by the API :
+The following sections outlines the primary methods provided by the API:
h4. gem(name, options = {})
Adds a +gem+ entry for the supplied gem to the generated application’s +Gemfile+.
-For example, if your application depends on the gems +bj+ and +nokogiri+ :
+For example, if your application depends on the gems +bj+ and +nokogiri+:
<ruby>
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. So you may want to run the +rake gems:install+ task too:
<ruby>
rake "gems:install"
@@ -80,13 +80,13 @@ h4. plugin(name, options = {})
Installs a plugin to the generated application.
-Plugin can be installed from Git :
+Plugin can be installed from Git:
<ruby>
plugin 'authentication', :git => 'git://github.com/foor/bar.git'
</ruby>
-You can even install plugins as git submodules :
+You can even install plugins as git submodules:
<ruby>
plugin 'authentication', :git => 'git://github.com/foor/bar.git',
@@ -95,7 +95,7 @@ plugin 'authentication', :git => 'git://github.com/foor/bar.git',
Please note that you need to +git :init+ before you can install a plugin as a submodule.
-Or use plain old SVN :
+Or use plain old SVN:
<ruby>
plugin 'usingsvn', :svn => 'svn://example.com/usingsvn/trunk'
@@ -105,7 +105,7 @@ h4. vendor/lib/file/initializer(filename, data = nil, &block)
Adds an initializer to the generated application’s +config/initializers+ directory.
-Lets say you like using +Object#not_nil?+ and +Object#not_blank?+ :
+Lets say you like using +Object#not_nil?+ and +Object#not_blank?+:
<ruby>
initializer 'bloatlol.rb', <<-CODE
@@ -123,7 +123,7 @@ CODE
Similarly +lib()+ creates a file in the +lib/+ directory and +vendor()+ creates a file in the +vendor/+ directory.
-There is even +file()+, which accepts a relative path from +Rails.root+ and creates all the directories/file needed :
+There is even +file()+, which accepts a relative path from +Rails.root+ and creates all the directories/file needed:
<ruby>
file 'app/components/foo.rb', <<-CODE
@@ -136,7 +136,7 @@ That’ll create +app/components+ directory and put +foo.rb+ in there.
h4. rakefile(filename, data = nil, &block)
-Creates a new rake file under +lib/tasks+ with the supplied tasks :
+Creates a new rake file under +lib/tasks+ with the supplied tasks:
<ruby>
rakefile("bootstrap.rake") do
@@ -154,7 +154,7 @@ The above creates +lib/tasks/bootstrap.rake+ with a +boot:strap+ rake task.
h4. generate(what, args)
-Runs the supplied rails generator with given arguments. For example, I love to scaffold some whenever I’m playing with Rails :
+Runs the supplied rails generator with given arguments. For example, I love to scaffold some whenever I’m playing with Rails:
<ruby>
generate(:scaffold, "person", "name:string", "address:text", "age:number")
@@ -162,7 +162,7 @@ generate(:scaffold, "person", "name:string", "address:text", "age:number")
h4. run(command)
-Executes an arbitrary command. Just like the backticks. Let's say you want to remove the +public/index.html+ file :
+Executes an arbitrary command. Just like the backticks. Let's say you want to remove the +public/index.html+ file:
<ruby>
run "rm public/index.html"
@@ -170,19 +170,19 @@ run "rm public/index.html"
h4. rake(command, options = {})
-Runs the supplied rake tasks in the Rails application. Let's say you want to migrate the database :
+Runs the supplied rake tasks in the Rails application. Let's say you want to migrate the database:
<ruby>
rake "db:migrate"
</ruby>
-You can also run rake tasks with a different Rails environment :
+You can also run rake tasks with a different Rails environment:
<ruby>
rake "db:migrate", :env => 'production'
</ruby>
-Or even use sudo :
+Or even use sudo:
<ruby>
rake "gems:install", :sudo => true
@@ -190,7 +190,7 @@ rake "gems:install", :sudo => true
h4. route(routing_code)
-This adds a routing entry to the +config/routes.rb+ file. In above steps, we generated a person scaffold and also removed +public/index.html+. Now to make +PeopleController#index+ as the default page for the application :
+This adds a routing entry to the +config/routes.rb+ file. In above steps, we generated a person scaffold and also removed +public/index.html+. Now to make +PeopleController#index+ as the default page for the application:
<ruby>
route "root :to => 'person#index'"
@@ -208,7 +208,7 @@ end
h4. ask(question)
-+ask()+ gives you a chance to get some feedback from the user and use it in your templates. Lets say you want your user to name the new shiny library you’re adding :
++ask()+ gives you a chance to get some feedback from the user and use it in your templates. Lets say you want your user to name the new shiny library you’re adding:
<ruby>
lib_name = ask("What do you want to call the shiny library ?")
@@ -222,7 +222,7 @@ CODE
h4. yes?(question) or no?(question)
-These methods let you ask questions from templates and decide the flow based on the user’s answer. Lets say you want to freeze rails only if the user want to :
+These methods let you ask questions from templates and decide the flow based on the user’s answer. Lets say you want to freeze rails only if the user want to:
<ruby>
rake("rails:freeze:gems") if yes?("Freeze rails gems ?")
@@ -231,7 +231,7 @@ no?(question) acts just the opposite.
h4. git(:must => "-a love")
-Rails templates let you run any git command :
+Rails templates let you run any git command:
<ruby>
git :init
diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile
index 58b75b9a1d..43c08165dc 100644
--- a/railties/guides/source/routing.textile
+++ b/railties/guides/source/routing.textile
@@ -321,7 +321,7 @@ resources :photos do
end
</ruby>
-This will recognize +/photos/1/preview+ with GET, and route to the +preview+ action of +PhotosController+. It will also create the +preview_photo_url+ and +preview_photo_path+ helpers.
+This will recognize +/photos/1/preview+ with GET, and route to the +preview+ action of +PhotosController+. It will also create the +preview_photo_url+ and +preview_photo_path+ helpers.
Within the block of member routes, each route name specifies the HTTP verb that it will recognize. You can use +get+, +put+, +post+, or +delete+ here. If you don't have multiple +member+ routes, you can also pass +:on+ to a route, eliminating the block:
@@ -421,7 +421,7 @@ You do not need to explicitly use the +:controller+ and +:action+ symbols within
match 'photos/:id' => 'photos#show'
</ruby>
-With this route, Rails will match an incoming path of +/photos/12+ to the +show+ action of +PhotosController+.
+With this route, Rails will match an incoming path of +/photos/12+ to the +show+ action of +PhotosController+.
You can also define other defaults in a route by supplying a hash for the +:defaults+ option. This even applies to parameters that you do not specify as dynamic segments. For example:
@@ -557,7 +557,7 @@ match '*a/foo/*b' => 'test#index'
would match +zoo/woo/foo/bar/baz+ with +params[:a]+ equals +"zoo/woo"+, and +params[:b]+ equals +"bar/baz"+.
-NOTE: Starting from Rails 3.1, wildcard route will always matching the optional format segment by default. For example if you have this route:
+NOTE: Starting from Rails 3.1, wildcard routes will always match the optional format segment by default. For example if you have this route:
<ruby>
map '*pages' => 'pages#show'
diff --git a/railties/guides/source/ruby_on_rails_guides_guidelines.textile b/railties/guides/source/ruby_on_rails_guides_guidelines.textile
index 8e55780dca..26a5a4c3c9 100644
--- a/railties/guides/source/ruby_on_rails_guides_guidelines.textile
+++ b/railties/guides/source/ruby_on_rails_guides_guidelines.textile
@@ -13,7 +13,7 @@ h3. Prologue
Each guide should start with motivational text at the top (that's the little introduction in the blue area.) The prologue should tell the reader what the guide is about, and what they will learn. See for example the "Routing Guide":routing.html.
h3. Titles
-
+
The title of every guide uses +h2+, guide sections use +h3+, subsections +h4+, etc.
Capitalize all words except for internal articles, prepositions, conjunctions, and forms of the verb to be:
diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile
index c9dc1c2d7c..f87ffdb20d 100644
--- a/railties/guides/source/security.textile
+++ b/railties/guides/source/security.textile
@@ -147,7 +147,7 @@ reset_session
If you use the popular RestfulAuthentication plugin for user management, add reset_session to the SessionsController#create action. Note that this removes any value from the session, _(highlight)you have to transfer them to the new session_.
-Another countermeasure is to _(highlight)save user-specific properties in the session_, verify them every time a request comes in, and deny access, if the information does not match. Such properties could be the remote IP address or the user agent (the web browser name), though the latter is less user-specific. When saving the IP address, you have to bear in mind that there are Internet service providers or large organizations that put their users behind proxies. _(highlight)These might change over the course of a session_, so these users will not be able to use your application, or only in a limited way.
+Another countermeasure is to _(highlight)save user-specific properties in the session_, verify them every time a request comes in, and deny access, if the information does not match. Such properties could be the remote IP address or the user agent (the web browser name), though the latter is less user-specific. When saving the IP address, you have to bear in mind that there are Internet service providers or large organizations that put their users behind proxies. _(highlight)These might change over the course of a session_, so these users will not be able to use your application, or only in a limited way.
h4. Session Expiry
@@ -238,7 +238,7 @@ Or the attacker places the code into the onmouseover event handler of an image:
<img src="http://www.harmless.com/img" width="400" height="400" onmouseover="..." />
</html>
-There are many other possibilities, including Ajax to attack the victim in the background.
The _(highlight)solution to this is including a security token in non-GET requests_ which check on the server-side. In Rails 2 or higher, this is a one-liner in the application controller:
+There are many other possibilities, including Ajax to attack the victim in the background.
The _(highlight)solution to this is including a security token in non-GET requests_ which check on the server-side. In Rails 2 or higher, this is a one-liner in the application controller:
<ruby>
protect_from_forgery :secret => "123456789012345678901234567890..."
@@ -394,7 +394,7 @@ params[:user] # => {:name => “ow3ned”, :admin => true}
So if you create a new user using mass-assignment, it may be too easy to become an administrator.
-Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the <tt>attributes=</tt> method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example:
+Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the <tt>attributes=</tt> method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example:
<ruby>
class Person < ActiveRecord::Base
@@ -418,10 +418,17 @@ To avoid this, Rails provides two class methods in your Active Record class to c
attr_protected :admin
</ruby>
++attr_protected+ also optionally takes a scope option using :as which allows you to define multiple mass-assignment groupings. If no scope is defined then attributes will be added to the default group.
+
+<ruby>
+attr_protected :last_login, :as => :admin
+</ruby>
+
A much better way, because it follows the whitelist-principle, is the +attr_accessible+ method. It is the exact opposite of +attr_protected+, because _(highlight)it takes a list of attributes that will be accessible_. All other attributes will be protected. This way you won't forget to protect attributes when adding new ones in the course of development. Here is an example:
<ruby>
attr_accessible :name
+attr_accessible :name, :is_admin, :as => :admin
</ruby>
If you want to set a protected attribute, you will to have to assign it individually:
@@ -434,13 +441,31 @@ params[:user] # => {:name => "ow3ned", :admin => true}
@user.admin # => true
</ruby>
-A more paranoid technique to protect your whole project would be to enforce that all models whitelist their accessible attributes. This can be easily achieved with a very simple initializer:
+When assigning attributes in Active Record using +new+, +attributes=+, or +update_attributes+ the :default scope will be used. To assign attributes using different scopes you should use +assign_attributes+ which accepts an optional :as options parameter. If no :as option is provided then the :default scope will be used. You can also bypass mass-assignment security by using the +:without_protection+ option. Here is an example:
+
+<ruby>
+@user = User.new
+
+@user.assign_attributes({ :name => 'Josh', :is_admin => true })
+@user.name # => Josh
+@user.is_admin # => false
+
+@user.assign_attributes({ :name => 'Josh', :is_admin => true }, :as => :admin)
+@user.name # => Josh
+@user.is_admin # => true
+
+@user.assign_attributes({ :name => 'Josh', :is_admin => true }, :without_protection => true)
+@user.name # => Josh
+@user.is_admin # => true
+</ruby>
+
+A more paranoid technique to protect your whole project would be to enforce that all models define their accessible attributes. This can be easily achieved with a very simple application config option of:
<ruby>
-ActiveRecord::Base.send(:attr_accessible, nil)
+config.active_record.whitelist_attributes = true
</ruby>
-This will create an empty whitelist of attributes available for mass assignment for all models in your app. As such, your models will need to explicitly whitelist accessible parameters by using an +attr_accessible+ declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to insert this initializer, run your tests, and expose each attribute (via +attr_accessible+) as dictated by your failing tests.
+This will create an empty whitelist of attributes available for mass-assignment for all models in your app. As such, your models will need to explicitly whitelist or blacklist accessible parameters by using an +attr_accessible+ or +attr_protected+ declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to use this application config option; run your tests, and expose each attribute (via +attr_accessible+ or +attr_protected+) as dictated by your failing tests.
h3. User Management
diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile
index e2317661ea..9b1ef22b97 100644
--- a/railties/guides/source/testing.textile
+++ b/railties/guides/source/testing.textile
@@ -415,8 +415,8 @@ NOTE: +assert_valid(record)+ has been deprecated. Please use +assert(record.vali
|_.Assertion |_.Purpose|
|+assert_valid(record)+ |Ensures that the passed record is valid by Active Record standards and returns any error messages if it is not.|
-|+assert_difference(expressions, difference = 1, message = nil) {...}+ |Test numeric difference between the return value of an expression as a result of what is evaluated in the yielded block.|
-|+assert_no_difference(expressions, message = nil, &amp;block)+ |Asserts that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.|
+|+assert_difference(expressions, difference = 1, message = nil) {...}+ |Test numeric difference between the return value of an expression as a result of what is evaluated in the yielded block.|
+|+assert_no_difference(expressions, message = nil, &amp;block)+ |Asserts that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.|
|+assert_recognizes(expected_options, path, extras={}, message=nil)+ |Asserts that the routing of the given path was handled correctly and that the parsed options (given in the expected_options hash) match path. Basically, it asserts that Rails recognizes the route given by expected_options.|
|+assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)+ |Asserts that the provided options can be used to generate the provided path. This is the inverse of assert_recognizes. The extras parameter is used to tell the request the names and values of additional request parameters that would be in a query string. The message parameter allows you to specify a custom error message for assertion failures.|
|+assert_response(type, message = nil)+ |Asserts that the response comes with a specific status code. You can specify +:success+ to indicate 200, +:redirect+ to indicate 300-399, +:missing+ to indicate 404, or +:error+ to match the 500-599 range|
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index e3942f0f1f..0c3c7737ea 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -50,6 +50,7 @@ module Rails
end
end
+ attr_accessor :assets
delegate :default_url_options, :default_url_options=, :to => :routes
# This method is called just after an application inherits from Rails::Application,
@@ -116,13 +117,10 @@ module Rails
self
end
- alias :build_middleware_stack :app
-
def env_config
@env_config ||= super.merge({
"action_dispatch.parameter_filter" => config.filter_parameters,
"action_dispatch.secret_token" => config.secret_token,
- "action_dispatch.asset_path" => nil,
"action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions
})
end
@@ -137,45 +135,9 @@ module Rails
@config ||= Application::Configuration.new(find_root_with_flag("config.ru", Dir.pwd))
end
- def assets
- @assets ||= build_asset_environment
- end
- attr_writer :assets
-
- def build_asset_environment
- return unless config.assets.enabled
- require 'sprockets'
- env = Sprockets::Environment.new(root.to_s)
- env.static_root = File.join(root.join("public"), config.assets.prefix)
- env
- end
-
- initializer :add_sprockets_paths do |app|
- if config.assets.enabled
- paths = [
- "app/assets/javascripts",
- "app/assets/stylesheets",
- "vendor/assets/javascripts",
- "vendor/assets/stylesheets",
- "vendor/plugins/*/app/javascripts",
- "vendor/plugins/*/app/stylesheets",
- "vendor/plugins/*/javascripts",
- "vendor/plugins/*/stylesheets"
- ] + config.assets.paths
-
- paths.each do |pattern|
- Dir[app.root.join(pattern)].each do |dir|
- app.assets.paths << dir
- end
- end
- end
- end
-
protected
- def default_asset_path
- nil
- end
+ alias :build_middleware_stack :app
def default_middleware_stack
ActionDispatch::MiddlewareStack.new.tap do |middleware|
@@ -190,8 +152,7 @@ module Rails
end
if config.serve_static_assets
- asset_paths = ActiveSupport::OrderedHash[config.static_asset_paths.to_a.reverse]
- middleware.use ::ActionDispatch::Static, asset_paths
+ middleware.use ::ActionDispatch::Static, paths["public"].first
end
middleware.use ::Rack::Lock unless config.allow_concurrency
@@ -239,4 +200,4 @@ module Rails
require "rails/console/helpers"
end
end
-end
+end \ No newline at end of file
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 4a042e0033..f818313955 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -4,13 +4,12 @@ require 'rails/engine/configuration'
module Rails
class Application
class Configuration < ::Rails::Engine::Configuration
- attr_accessor :allow_concurrency, :asset_host, :cache_classes, :cache_store,
- :encoding, :consider_all_requests_local, :dependency_loading,
- :filter_parameters, :helpers_paths, :logger,
- :preload_frameworks, :reload_plugins,
- :secret_token, :serve_static_assets, :session_options,
- :time_zone, :whiny_nils, :force_ssl,
- :assets
+ attr_accessor :allow_concurrency, :asset_host, :asset_path, :assets,
+ :cache_classes, :cache_store, :consider_all_requests_local,
+ :dependency_loading, :encoding, :filter_parameters,
+ :force_ssl, :helpers_paths, :logger, :preload_frameworks,
+ :reload_plugins, :secret_token, :serve_static_assets,
+ :session_options, :time_zone, :whiny_nils
attr_writer :log_level
@@ -34,8 +33,11 @@ module Rails
@assets = ActiveSupport::OrderedOptions.new
@assets.enabled = false
@assets.paths = []
- @assets.precompile = []
+ @assets.precompile = [ /\w+\.(?!js|css)$/, "application.js", "application.css" ]
@assets.prefix = "/assets"
+
+ @assets.js_compressor = nil
+ @assets.css_compressor = nil
end
def compiled_asset_path
@@ -63,6 +65,9 @@ module Rails
paths.add "config/environment", :with => "config/environment.rb"
paths.add "lib/templates"
paths.add "log", :with => "log/#{Rails.env}.log"
+ paths.add "public"
+ paths.add "public/javascripts"
+ paths.add "public/stylesheets"
paths.add "tmp"
paths.add "tmp/cache"
paths
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index bae464a840..028c8814c4 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -33,27 +33,6 @@ module Rails
end
end
- initializer :add_sprockets_route do |app|
- assets = config.assets
- if assets.enabled
- app.routes.append do
- mount app.assets => assets.prefix
- end
- end
- end
-
- initializer :set_sprockets_logger do |app|
- if config.assets.enabled
- app.assets.logger = Rails.logger
- end
- end
-
- initializer :index_sprockets_environment do |app|
- if config.assets.enabled && config.action_controller.perform_caching
- app.assets = app.assets.index
- end
- end
-
initializer :build_middleware_stack do
build_middleware_stack
end
@@ -62,6 +41,10 @@ module Rails
ActionDispatch::Reloader.prepare!
end
+ initializer :define_main_app_helper do |app|
+ app.routes.define_mounted_helper(:main_app)
+ end
+
initializer :eager_load! do
if config.cache_classes && !$rails_rake_task
ActiveSupport.run_load_hooks(:before_eager_load, self)
@@ -74,6 +57,8 @@ module Rails
end
# Force routes to be loaded just at the end and add it to to_prepare callbacks
+ # This needs to be after the finisher hook to ensure routes added in the hook
+ # are still loaded.
initializer :set_routes_reloader do |app|
reloader = lambda { app.routes_reloader.execute_if_updated }
reloader.call
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index ee265366ff..6c1064c609 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -171,32 +171,6 @@ module Rails
#
# Now, +Engine+ will get only requests that were not handled by +Application+.
#
- # == Asset path
- #
- # When you use +Engine+ with its own public directory, you will probably want to copy or symlink it
- # to application's public directory. To simplify generating paths for assets, you can set <tt>asset_path</tt>
- # for an engine:
- #
- # module MyEngine
- # class Engine < Rails::Engine
- # config.asset_path = "/my_engine/%s"
- # end
- # end
- #
- # With such a config, asset paths will be automatically modified inside +Engine+:
- #
- # image_path("foo.jpg") #=> "/my_engine/images/foo.jpg"
- #
- # == Serving static files
- #
- # By default, Rails uses <tt>ActionDispatch::Static</tt> to serve static files in development mode. This is ok
- # while you develop your application, but when you want to deploy it, assets from an engine will not be
- # served by default. You should choose one of the two following strategies:
- #
- # * enable serving static files by setting config.serve_static_assets to true
- # * copy engine's public files to application's public folder with <tt>rake ENGINE_NAME:install:assets</tt>, for example
- # <tt>rake my_engine:install:assets</tt>
- #
# == Engine name
#
# There are some places where an Engine's name is used:
@@ -312,6 +286,27 @@ module Rails
#
# This code will use <tt>my_engine.user_path(@user)</tt> to generate the proper route.
#
+ # == Isolated engine's helpers
+ #
+ # Sometimes you may want to isolate engine, but use helpers that are defined for it.
+ # If you want to share just a few specific helpers you can add them to application's
+ # helpers in ApplicationController:
+ #
+ # class ApplicationController < ActionController::Base
+ # helper MyEngine::SharedEngineHelper
+ # end
+ #
+ # If you want to include all of the engine's helpers, you can use #helpers method on egine's
+ # instance:
+ #
+ # class ApplicationController < ActionController::Base
+ # helper MyEngine::Engine.helpers
+ # end
+ #
+ # It will include all of the helpers from engine's directory. Take into account that this does
+ # not include helpers defined in controllers with helper_method or other similar solutions,
+ # only helpers defined in helpers directory will be included.
+ #
# == Migrations & seed data
#
# Engines can have their own migrations. The default path for migrations is exactly the same
@@ -410,6 +405,24 @@ module Rails
@railties ||= self.class::Railties.new(config)
end
+ def helpers
+ @helpers ||= begin
+ helpers = Module.new
+
+ helpers_paths = if config.respond_to?(:helpers_paths)
+ config.helpers_paths
+ else
+ paths["app/helpers"].existent
+ end
+
+ all = ActionController::Base.all_helpers_from_path(helpers_paths)
+ ActionController::Base.modules_for_helpers(all).each do |mod|
+ helpers.send(:include, mod)
+ end
+ helpers
+ end
+ end
+
def app
@app ||= begin
config.middleware = config.middleware.merge_into(default_middleware_stack)
@@ -427,8 +440,7 @@ module Rails
def env_config
@env_config ||= {
- 'action_dispatch.routes' => routes,
- 'action_dispatch.asset_path' => config.asset_path
+ 'action_dispatch.routes' => routes
}
end
@@ -509,13 +521,9 @@ module Rails
require environment if environment
end
- initializer :append_asset_paths do
- config.asset_path ||= default_asset_path
-
- public_path = paths["public"].first
- if config.compiled_asset_path && File.exist?(public_path)
- config.static_asset_paths[config.compiled_asset_path] = public_path
- end
+ initializer :append_assets_path do |app|
+ app.config.assets.paths.unshift *paths["vendor/assets"].existent
+ app.config.assets.paths.unshift *paths["app/assets"].existent
end
initializer :prepend_helpers_path do |app|
@@ -537,42 +545,29 @@ module Rails
rake_tasks do
next if self.is_a?(Rails::Application)
+ next unless has_migrations?
namespace railtie_name do
- desc "Shortcut for running both rake #{railtie_name}:install:migrations and #{railtie_name}:install:assets"
- task :install do
- Rake::Task["#{railtie_name}:install:migrations"].invoke
- Rake::Task["#{railtie_name}:install:assets"].invoke
- end
-
namespace :install do
- # TODO Add assets copying to this list
- # TODO Skip this if there is no paths["db/migrate"] for the engine
desc "Copy migrations from #{railtie_name} to application"
task :migrations do
ENV["FROM"] = railtie_name
Rake::Task["railties:install:migrations"].invoke
end
-
- desc "Copy assets from #{railtie_name} to application"
- task :assets do
- ENV["FROM"] = railtie_name
- Rake::Task["railties:install:assets"].invoke
- end
end
end
end
protected
- def default_asset_path
- "/#{railtie_name}%s"
- end
-
def routes?
defined?(@routes)
end
+ def has_migrations?
+ paths["db/migrate"].first.present?
+ end
+
def find_root_with_flag(flag, default=nil)
root_path = self.class.called_from
diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb
index 4f458b0aee..241db4b0a9 100644
--- a/railties/lib/rails/engine/configuration.rb
+++ b/railties/lib/rails/engine/configuration.rb
@@ -5,7 +5,7 @@ module Rails
class Configuration < ::Rails::Railtie::Configuration
attr_reader :root
attr_writer :middleware, :eager_load_paths, :autoload_once_paths, :autoload_paths
- attr_accessor :plugins, :asset_path
+ attr_accessor :plugins
def initialize(root=nil)
super()
@@ -40,6 +40,7 @@ module Rails
@paths ||= begin
paths = Rails::Paths::Root.new(@root)
paths.add "app", :eager_load => true, :glob => "*"
+ paths.add "app/assets", :glob => "*"
paths.add "app/controllers", :eager_load => true
paths.add "app/helpers", :eager_load => true
paths.add "app/models", :eager_load => true
@@ -55,10 +56,8 @@ module Rails
paths.add "db"
paths.add "db/migrate"
paths.add "db/seeds", :with => "db/seeds.rb"
- paths.add "public"
- paths.add "public/javascripts"
- paths.add "public/stylesheets"
paths.add "vendor", :load_path => true
+ paths.add "vendor/assets", :glob => "*"
paths.add "vendor/plugins"
paths
end
@@ -79,10 +78,6 @@ module Rails
def autoload_paths
@autoload_paths ||= paths.autoload_paths
end
-
- def compiled_asset_path
- asset_path % "" if asset_path
- end
end
end
end
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index be61b087f9..9be395e989 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -24,9 +24,12 @@ module Rails
:rails => {
:actions => '-a',
:orm => '-o',
+ :javascripts => '-j',
+ :javascript_engine => '-je',
:resource_controller => '-c',
:scaffold_controller => '-c',
:stylesheets => '-y',
+ :stylesheet_engine => '-se',
:template_engine => '-e',
:test_framework => '-t'
},
@@ -43,15 +46,18 @@ module Rails
DEFAULT_OPTIONS = {
:rails => {
+ :assets => true,
:force_plural => false,
:helper => true,
- :assets => true,
- :orm => nil,
:integration_tool => nil,
+ :javascripts => true,
+ :javascript_engine => nil,
+ :orm => nil,
:performance_tool => nil,
:resource_controller => :controller,
:scaffold_controller => :scaffold_controller,
:stylesheets => true,
+ :stylesheet_engine => nil,
:test_framework => nil,
:template_engine => :erb
},
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 481fa95068..46a2a3f154 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -10,6 +10,8 @@ module Rails
module Generators
class AppBase < Base
DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
+ JDBC_DATABASES = %w( jdbcmysql jdbcsqlite3 )
+ DATABASES.concat(JDBC_DATABASES)
JAVASCRIPTS = %w( jquery prototype )
attr_accessor :rails_template
@@ -156,12 +158,14 @@ module Rails
end
def gem_for_database
- # %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
+ # %w( mysql oracle postgresql sqlite3 frontbase ibm_db jdbcmysql jdbcsqlite3)
case options[:database]
when "oracle" then "ruby-oci8"
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"
else options[:database]
end
end
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 93d6c1f827..bc55efa261 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -89,10 +89,6 @@ module Rails
directory "public", "public", :recursive => false
end
- def images
- directory "public/images"
- end
-
def script
directory "script" do |content|
"#{shebang}\n" + content
@@ -106,7 +102,8 @@ module Rails
empty_directory_with_gitkeep "test/integration"
empty_directory_with_gitkeep "test/unit"
- copy_file "test/performance/browsing_test.rb"
+ template "test/performance/browsing_test.rb"
+ template "test/test_helper.rb"
end
def tmp
@@ -137,7 +134,7 @@ module Rails
def vendor_stylesheets
empty_directory_with_gitkeep "vendor/assets/stylesheets"
end
-
+
def vendor_plugins
empty_directory_with_gitkeep "vendor/plugins"
end
@@ -165,7 +162,7 @@ module Rails
if !options[:skip_active_record] && !DATABASES.include?(options[:database])
raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
end
-
+
if !options[:skip_javascript] && !JAVASCRIPTS.include?(options[:javascript])
raise Error, "Invalid value for --javascript option. Supported for preconfiguration are: #{JAVASCRIPTS.join(", ")}."
end
@@ -218,10 +215,6 @@ module Rails
build(:public_directory)
end
- def create_public_image_files
- build(:images)
- end
-
def create_script_files
build(:script)
end
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index 0cee7deb72..9f2346028a 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -6,8 +6,9 @@ source 'http://rubygems.org'
# Asset template engines
<%= "gem 'json'\n" if RUBY_VERSION < "1.9.2" -%>
-gem 'sass', '~> 3.1.0.alpha'
+gem 'sass'
gem 'coffee-script'
+# gem 'uglifier'
# Use unicorn as the web server
# gem 'unicorn'
diff --git a/railties/lib/rails/generators/rails/app/templates/public/images/rails.png b/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png
index d5edc04e65..d5edc04e65 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/images/rails.png
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png
Binary files differ
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
index 8b8ba74c01..fb5e91caf4 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
@@ -1,11 +1,11 @@
-# FIXME: Tell people that this is a manifest file, real code should go into discrete files
-# FIXME: Tell people how Sprockets and CoffeeScript works
-#
-#= require <%= options[:javascript] %>
-#= require <%= options[:javascript] %>_ujs
+// FIXME: Tell people that this is a manifest file, real code should go into discrete files
+// FIXME: Tell people how Sprockets and CoffeeScript works
+//
+//= require <%= options[:javascript] %>
+//= require <%= options[:javascript] %>_ujs
<% if options[:javascript] == "prototype" %>
-#= require controls
-#= require dragdrop
-#= require effects
+//= require controls
+//= require dragdrop
+//= require effects
<% end -%>
-#= require_tree .
+//= require_tree .
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
new file mode 100644
index 0000000000..ca807c9f3f
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
@@ -0,0 +1,30 @@
+# MySQL. Versions 4.1 and 5.0 are recommended.
+#
+# Install the MySQL driver:
+# gem install activerecord-jdbcmysql-adapter
+#
+# And be sure to use new-style password hashing:
+# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
+development:
+ adapter: jdbcmysql
+ database: <%= app_name %>_development
+ username: root
+ password:
+ host: localhost
+
+# 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: jdbcmysql
+ database: <%= app_name %>_test
+ username: root
+ password:
+ host: localhost
+
+production:
+ adapter: jdbcmysql
+ database: <%= app_name %>_production
+ username: root
+ password:
+ host: localhost
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
new file mode 100644
index 0000000000..30776b3b4e
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
@@ -0,0 +1,17 @@
+# SQLite version 3.x
+# gem 'activerecord-jdbcsqlite3-adapter'
+
+development:
+ adapter: jdbcsqlite3
+ 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
+ database: db/test.sqlite3
+
+production:
+ adapter: jdbcsqlite3
+ database: db/production.sqlite3
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 874cc403ba..ce28e41b91 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
@@ -15,6 +15,10 @@
# (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
+ # Compress both stylesheets and JavaScripts
+ # config.assets.js_compressor = :uglifier
+ config.assets.css_compressor = :scss
+
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
@@ -30,6 +34,9 @@
# Enable serving of images, stylesheets, and javascripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
+ # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
+ # config.assets.precompile += %w( search.js )
+
# Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false
diff --git a/railties/lib/rails/generators/rails/app/templates/db/seeds.rb b/railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt
index 9a2efa68a7..9a2efa68a7 100644
--- a/railties/lib/rails/generators/rails/app/templates/db/seeds.rb
+++ b/railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/public/index.html b/railties/lib/rails/generators/rails/app/templates/public/index.html
index 13a203dd08..9d9811a5bf 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/index.html
+++ b/railties/lib/rails/generators/rails/app/templates/public/index.html
@@ -59,7 +59,7 @@
#header {
- background-image: url("images/rails.png");
+ background-image: url("/assets/rails.png");
background-repeat: no-repeat;
background-position: top left;
height: 64px;
diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb
index a8f7aeac7d..a8f7aeac7d 100644
--- a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb
diff --git a/railties/lib/rails/generators/rails/assets/assets_generator.rb b/railties/lib/rails/generators/rails/assets/assets_generator.rb
index 59239d1a03..80beb7abfe 100644
--- a/railties/lib/rails/generators/rails/assets/assets_generator.rb
+++ b/railties/lib/rails/generators/rails/assets/assets_generator.rb
@@ -1,36 +1,38 @@
module Rails
module Generators
- # TODO: Add hooks for using other asset pipelines, like Less
class AssetsGenerator < NamedBase
- def create_asset_files
+ class_option :javascripts, :type => :boolean, :desc => "Generate javascripts"
+ class_option :stylesheets, :type => :boolean, :desc => "Generate stylesheets"
+
+ 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', "#{file_name}.#{javascript_extension}")
+ File.join('app/assets/javascripts', class_path, "#{asset_name}.#{javascript_extension}")
+ end
+ def create_stylesheet_files
+ return unless options.stylesheets?
copy_file "stylesheet.#{stylesheet_extension}",
- File.join('app/assets/stylesheets', "#{file_name}.#{stylesheet_extension}")
+ File.join('app/assets/stylesheets', class_path, "#{asset_name}.#{stylesheet_extension}")
end
-
- private
- def javascript_extension
- using_coffee? ? "js.coffee" : "js"
+
+ protected
+
+ def asset_name
+ file_name
end
-
- def using_coffee?
- require 'coffee-script'
- defined?(CoffeeScript)
- rescue LoadError
- false
+
+ def javascript_extension
+ options.javascript_engine.present? ?
+ "js.#{options.javascript_engine}" : "js"
end
-
+
def stylesheet_extension
- using_sass? ? "css.scss" : "css"
- end
-
- def using_sass?
- require 'sass'
- defined?(Sass)
- rescue LoadError
- false
+ options.stylesheet_engine.present? ?
+ "css.#{options.stylesheet_engine}" : "css"
end
end
end
diff --git a/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee b/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee
index 09b2da094a..761567942f 100644
--- a/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee
+++ b/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee
@@ -1,3 +1,3 @@
-// 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/
+# 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 3cf8410d1e..126aadb88d 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
@@ -9,10 +9,17 @@ module Rails
end
def app
- if options[:mountable]
+ if mountable?
directory "app"
template "#{app_templates_dir}/app/views/layouts/application.html.erb.tt",
"app/views/layouts/#{name}/application.html.erb"
+ empty_directory_with_gitkeep "app/assets/images"
+ 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"
end
end
@@ -61,8 +68,12 @@ task :default => :test
end
end
+ PASSTHROUGH_OPTIONS = [
+ :skip_active_record, :skip_javascript, :database, :javascript, :quiet, :pretend, :force, :skip
+ ]
+
def generate_test_dummy(force = false)
- opts = (options || {}).slice(:skip_active_record, :skip_javascript, :database, :javascript, :quiet, :pretend, :force, :skip)
+ opts = (options || {}).slice(*PASSTHROUGH_OPTIONS)
opts[:force] = force
invoke Rails::Generators::AppGenerator,
@@ -84,7 +95,7 @@ task :default => :test
remove_file "doc"
remove_file "Gemfile"
remove_file "lib/tasks"
- remove_file "public/images/rails.png"
+ remove_file "app/assets/images/rails.png"
remove_file "public/index.html"
remove_file "public/robots.txt"
remove_file "README"
@@ -94,26 +105,36 @@ task :default => :test
end
def stylesheets
- empty_directory_with_gitkeep "public/stylesheets" if options[:mountable]
+ if mountable?
+ copy_file "#{app_templates_dir}/app/assets/stylesheets/application.css",
+ "app/assets/stylesheets/application.css"
+ elsif full?
+ empty_directory_with_gitkeep "app/assets/stylesheets"
+ end
end
def javascripts
- return unless options[:mountable]
-
- empty_directory "#{app_templates_dir}/public/javascripts"
+ return if options.skip_javascript?
- unless options[:skip_javascript]
- copy_file "#{app_templates_dir}/public/javascripts/#{options[:javascript]}.js", "public/javascripts/#{options[:javascript]}.js"
- copy_file "#{app_templates_dir}/public/javascripts/#{options[:javascript]}_ujs.js", "public/javascripts/rails.js"
+ if mountable?
+ copy_file "#{app_templates_dir}/app/assets/javascripts/application.js.tt",
+ "app/assets/javascripts/application.js"
+ copy_file "#{app_templates_dir}/vendor/assets/javascripts/#{options[:javascript]}.js",
+ "vendor/assets/javascripts/#{options[:javascript]}.js"
+ copy_file "#{app_templates_dir}/vendor/assets/javascripts/#{options[:javascript]}_ujs.js",
+ "vendor/assets/javascripts/#{options[:javascript]}_ujs.js"
if options[:javascript] == "prototype"
- copy_file "#{app_templates_dir}/public/javascripts/controls.js", "public/javascripts/controls.js"
- copy_file "#{app_templates_dir}/public/javascripts/dragdrop.js", "public/javascripts/dragdrop.js"
- copy_file "#{app_templates_dir}/public/javascripts/effects.js", "public/javascripts/effects.js"
+ copy_file "#{app_templates_dir}/vendor/assets/javascripts/controls.js",
+ "vendor/assets/javascripts/controls.js"
+ copy_file "#{app_templates_dir}/vendor/assets/javascripts/dragdrop.js",
+ "vendor/assets/javascripts/dragdrop.js"
+ copy_file "#{app_templates_dir}/vendor/assets/javascripts/effects.js",
+ "vendor/assets/javascripts/effects.js"
end
+ elsif full?
+ empty_directory_with_gitkeep "app/assets/javascripts"
end
-
- copy_file "#{app_templates_dir}/public/javascripts/application.js", "public/javascripts/application.js"
end
def script(force = false)
@@ -130,17 +151,17 @@ task :default => :test
alias_method :plugin_path, :app_path
- class_option :dummy_path, :type => :string, :default => "test/dummy",
- :desc => "Create dummy application at given path"
+ class_option :dummy_path, :type => :string, :default => "test/dummy",
+ :desc => "Create dummy application at given path"
- class_option :full, :type => :boolean, :default => false,
- :desc => "Generate rails engine with integration tests"
+ class_option :full, :type => :boolean, :default => false,
+ :desc => "Generate rails engine with integration tests"
- class_option :mountable, :type => :boolean, :default => false,
- :desc => "Generate mountable isolated application"
+ class_option :mountable, :type => :boolean, :default => false,
+ :desc => "Generate mountable isolated application"
- class_option :skip_gemspec, :type => :boolean, :default => false,
- :desc => "Skip gemspec file"
+ class_option :skip_gemspec, :type => :boolean, :default => false,
+ :desc => "Skip gemspec file"
def initialize(*args)
raise Error, "Options should be given after the plugin name. For details run: rails plugin --help" if args[0].blank?
@@ -180,6 +201,10 @@ task :default => :test
build(:javascripts)
end
+ def create_images_directory
+ build(:images)
+ end
+
def create_script_files
build(:script)
end
@@ -200,6 +225,7 @@ task :default => :test
public_task :apply_rails_template, :bundle_if_dev_or_edge
protected
+
def app_templates_dir
"../../app/templates"
end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory b/railties/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb
index dd4d2da4eb..824caecb24 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb
@@ -5,9 +5,8 @@ class NavigationTest < ActionDispatch::IntegrationTest
fixtures :all
<% end -%>
- # Replace this with your real tests.
- test "the truth" do
- assert true
- end
+ # test "the truth" do
+ # assert true
+ # end
end
diff --git a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
index 779f933785..6eef0dbe5b 100644
--- a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
@@ -6,8 +6,27 @@ module Rails
remove_hook_for :resource_controller
remove_class_option :actions
+ class_option :stylesheets, :type => :boolean, :desc => "Generate stylesheets"
+ class_option :stylesheet_engine, :desc => "Engine for stylesheets"
+
hook_for :scaffold_controller, :required => true
- hook_for :stylesheets
+
+ def copy_stylesheets_file
+ if behavior == :invoke && options.stylesheets?
+ template "scaffold.#{stylesheet_extension}", "app/assets/stylesheets/scaffold.#{stylesheet_extension}"
+ end
+ end
+
+ hook_for :assets do |assets|
+ invoke assets, [controller_name]
+ end
+
+ private
+
+ def stylesheet_extension
+ options.stylesheet_engine.present? ?
+ "css.#{options.stylesheet_engine}" : "css"
+ end
end
end
end
diff --git a/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css
index 1ae7000299..1ae7000299 100644
--- a/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css
+++ b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css
diff --git a/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css.scss b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss
index 45116b53f6..45116b53f6 100644
--- a/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css.scss
+++ b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss
diff --git a/railties/lib/rails/generators/rails/stylesheets/USAGE b/railties/lib/rails/generators/rails/stylesheets/USAGE
deleted file mode 100644
index 59e5495d0b..0000000000
--- a/railties/lib/rails/generators/rails/stylesheets/USAGE
+++ /dev/null
@@ -1,5 +0,0 @@
-Description:
- Copies scaffold stylesheets to public/stylesheets/.
-
-Examples:
- `rails generate stylesheets`
diff --git a/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb b/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb
deleted file mode 100644
index d06db25292..0000000000
--- a/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-module Rails
- module Generators
- class StylesheetsGenerator < Base
- def copy_stylesheets_file
- if behavior == :invoke
- template "scaffold.#{stylesheet_extension}", "app/assets/stylesheets/scaffold.#{stylesheet_extension}"
- end
- end
-
- private
- def stylesheet_extension
- using_sass? ? "css.scss" : "css"
- end
-
- def using_sass?
- require 'sass'
- defined?(Sass)
- rescue LoadError
- false
- end
- end
- end
-end
diff --git a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
index 11a73ebad7..0bc5fd8ca2 100644
--- a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
@@ -3,10 +3,9 @@ require 'test_helper'
<% module_namespacing do -%>
class <%= class_name %>ControllerTest < ActionController::TestCase
<% if actions.empty? -%>
- # Replace this with your real tests.
- test "the truth" do
- assert true
- end
+ # test "the truth" do
+ # assert true
+ # end
<% else -%>
<% for action in actions -%>
test "should get <%= action %>" do
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 de0823749c..e7a06e4a73 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
@@ -3,8 +3,7 @@ require 'test_helper'
class <%= class_name %>Test < ActionDispatch::IntegrationTest
fixtures :all
- # Replace this with your real tests.
- test "the truth" do
- assert true
- end
+ # test "the truth" do
+ # assert true
+ # end
end
diff --git a/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb
index b62c7fd279..c05102290c 100644
--- a/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb
@@ -13,10 +13,9 @@ class <%= class_name %>Test < ActionMailer::TestCase
<% end -%>
<% if actions.blank? -%>
- # replace this with your real tests
- test "the truth" do
- assert true
- end
+ # test "the truth" do
+ # assert true
+ # end
<% end -%>
end
<% end -%>
diff --git a/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb b/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb
index 6f79879838..c9bc7d5b90 100644
--- a/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb
+++ b/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb
@@ -2,9 +2,8 @@ require 'test_helper'
<% module_namespacing do -%>
class <%= class_name %>Test < ActiveSupport::TestCase
- # Replace this with your real tests.
- test "the truth" do
- assert true
- end
+ # test "the truth" do
+ # assert true
+ # end
end
<% end -%>
diff --git a/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb b/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb
index cd116f5ce9..28aa23626a 100644
--- a/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb
+++ b/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb
@@ -2,9 +2,8 @@ require 'test_helper'
<% module_namespacing do -%>
class <%= class_name %>ObserverTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- test "the truth" do
- assert true
- end
+ # test "the truth" do
+ # assert true
+ # end
end
<% end -%>
diff --git a/railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt b/railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt
index 3e0bc29d3a..0cbae1120e 100644
--- a/railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt
+++ b/railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt
@@ -1,8 +1,7 @@
require 'test_helper'
class <%= class_name %>Test < ActiveSupport::TestCase
- # Replace this with your real tests.
- test "the truth" do
- assert true
- end
+ # test "the truth" do
+ # assert true
+ # end
end
diff --git a/railties/lib/rails/railtie/configuration.rb b/railties/lib/rails/railtie/configuration.rb
index 2c7b5bc048..bfd2a73aeb 100644
--- a/railties/lib/rails/railtie/configuration.rb
+++ b/railties/lib/rails/railtie/configuration.rb
@@ -67,13 +67,6 @@ module Rails
super || @@options.key?(name.to_sym)
end
- # static_asset_paths is a Hash containing asset_paths
- # with associated public folders, like:
- # { "/" => "/app/public", "/my_engine" => "app/engines/my_engine/public" }
- def static_asset_paths
- @@static_asset_paths ||= ActiveSupport::OrderedHash.new
- end
-
private
def method_missing(name, *args, &blk)
diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb
index 4d09b0c2c0..166d518f7c 100644
--- a/railties/lib/rails/tasks.rb
+++ b/railties/lib/rails/tasks.rb
@@ -12,7 +12,6 @@ $VERBOSE = nil
routes
statistics
tmp
- railties
).each do |task|
load "rails/tasks/#{task}.rake"
end
diff --git a/railties/lib/rails/tasks/assets.rake b/railties/lib/rails/tasks/assets.rake
index 396ce728a1..158df31749 100644
--- a/railties/lib/rails/tasks/assets.rake
+++ b/railties/lib/rails/tasks/assets.rake
@@ -1,5 +1,9 @@
namespace :assets do
- task :compile => :environment do
+ desc "Compile all the assets named in config.assets.precompile"
+ task :precompile => :environment do
+ # Give assets access to asset_path
+ ActionView::Helpers::SprocketsHelper
+
assets = Rails.application.config.assets.precompile
Rails.application.assets.precompile(*assets)
end
diff --git a/railties/lib/rails/tasks/railties.rake b/railties/lib/rails/tasks/railties.rake
deleted file mode 100644
index 16703879cf..0000000000
--- a/railties/lib/rails/tasks/railties.rake
+++ /dev/null
@@ -1,29 +0,0 @@
-namespace :railties do
- namespace :install do
- # desc "Copies missing assets from Railties (e.g. plugins, engines). You can specify Railties to use with FROM=railtie1,railtie2"
- task :assets => :rails_env do
- require 'rails/generators/base'
- Rails.application.initialize!
-
- to_load = ENV["FROM"].blank? ? :all : ENV["FROM"].split(",").map {|n| n.strip }
- app_public_path = Rails.application.paths["public"].first
-
- Rails.application.railties.all do |railtie|
- next unless to_load == :all || to_load.include?(railtie.railtie_name)
-
- if railtie.respond_to?(:paths) && (path = railtie.paths["public"].first) &&
- (assets_dir = railtie.config.compiled_asset_path) && File.exist?(path)
-
- Rails::Generators::Base.source_root(path)
- copier = Rails::Generators::Base.new
- Dir[File.join(path, "**/*")].each do |file|
- relative = file.gsub(/^#{path}\//, '')
- if File.file?(file)
- copier.copy_file relative, File.join(app_public_path, assets_dir, relative)
- end
- end
- end
- end
- end
- end
-end
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 62697b1bf9..ab3eb4c9e7 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -258,6 +258,18 @@ module ApplicationTests
assert_equal res, last_response.body # value should be unchanged
end
+ test "sets all Active Record models to whitelist all attributes by default" do
+ add_to_config <<-RUBY
+ config.active_record.whitelist_attributes = true
+ RUBY
+
+ require "#{app_path}/config/environment"
+
+ assert_equal ActiveModel::MassAssignmentSecurity::WhiteList,
+ ActiveRecord::Base.active_authorizers[:default].class
+ assert_equal [""], ActiveRecord::Base.active_authorizers[:default].to_a
+ end
+
test "registers interceptors with ActionMailer" do
add_to_config <<-RUBY
config.action_mailer.interceptors = MyMailInterceptor
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index dfb7adf459..839f75d963 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -8,6 +8,8 @@ DEFAULT_APP_FILES = %w(
Gemfile
Rakefile
config.ru
+ app/assets/javascripts
+ app/assets/stylesheets
app/controllers
app/helpers
app/mailers
@@ -21,9 +23,7 @@ DEFAULT_APP_FILES = %w(
lib
lib/tasks
log
- public/images
- public/javascripts
- public/stylesheets
+ app/assets/images
script/rails
test/fixtures
test/functional
@@ -31,11 +31,9 @@ DEFAULT_APP_FILES = %w(
test/performance
test/unit
vendor
+ vendor/assets
vendor/plugins
- tmp/sessions
- tmp/sockets
tmp/cache
- tmp/pids
)
class AppGeneratorTest < Rails::Generators::TestCase
@@ -49,8 +47,9 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_application_controller_and_layout_files
run_generator
- assert_file "app/views/layouts/application.html.erb", /stylesheet_link_tag :all/
- assert_no_file "public/stylesheets/application.css"
+ 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"
end
def test_invalid_application_name_raises_an_error
@@ -132,6 +131,18 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file "Gemfile", /^gem\s+["']mysql2["']$/
end
+ def test_config_jdbcmysql_database
+ run_generator([destination_root, "-d", "jdbcmysql"])
+ assert_file "config/database.yml", /jdbcmysql/
+ assert_file "Gemfile", /^gem\s+["']activerecord-jdbcmysql-adapter["']$/
+ end
+
+ def test_config_jdbcsqlite3_database
+ run_generator([destination_root, "-d", "jdbcsqlite3"])
+ assert_file "config/database.yml", /jdbcsqlite3/
+ assert_file "Gemfile", /^gem\s+["']activerecord-jdbcsqlite3-adapter["']$/
+ end
+
def test_generator_if_skip_active_record_is_given
run_generator [destination_root, "--skip-active-record"]
assert_no_file "config/database.yml"
@@ -149,37 +160,37 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_jquery_and_test_unit_are_added_by_default
run_generator
assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/
- assert_file "public/javascripts/application.js"
- assert_file "public/javascripts/jquery.js"
- assert_file "public/javascripts/rails.js"
+ assert_file "app/assets/javascripts/application.js"
+ assert_file "vendor/assets/javascripts/jquery.js"
+ assert_file "vendor/assets/javascripts/jquery_ujs.js"
assert_file "test"
end
def test_javascript_is_skipped_if_required
run_generator [destination_root, "--skip-javascript"]
assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(\)/
- assert_file "public/javascripts/application.js"
- assert_no_file "public/javascripts/jquery.js"
- assert_no_file "public/javascripts/rails.js"
+ assert_file "app/assets/javascripts/application.js"
+ assert_no_file "vendor/assets/javascripts/jquery.js"
+ assert_no_file "vendor/assets/javascripts/jquery_ujs.js"
end
def test_config_prototype_javascript_library
run_generator [destination_root, "-j", "prototype"]
assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/
- assert_file "public/javascripts/application.js"
- assert_file "public/javascripts/prototype.js"
- assert_file "public/javascripts/effects.js"
- assert_file "public/javascripts/dragdrop.js"
- assert_file "public/javascripts/controls.js"
- assert_file "public/javascripts/rails.js", /prototype/
+ assert_file "app/assets/javascripts/application.js"
+ assert_file "vendor/assets/javascripts/prototype.js"
+ assert_file "vendor/assets/javascripts/effects.js"
+ assert_file "vendor/assets/javascripts/dragdrop.js"
+ assert_file "vendor/assets/javascripts/controls.js"
+ assert_file "vendor/assets/javascripts/prototype_ujs.js", /prototype/
end
def test_config_jquery_javascript_library
run_generator [destination_root, "-j", "jquery"]
assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/
- assert_file "public/javascripts/application.js"
- assert_file "public/javascripts/jquery.js"
- assert_file "public/javascripts/rails.js", /jQuery/
+ assert_file "app/assets/javascripts/application.js"
+ assert_file "vendor/assets/javascripts/jquery.js"
+ assert_file "vendor/assets/javascripts/jquery_ujs.js", /jQuery/
end
def test_template_from_dir_pwd
diff --git a/railties/test/generators/assets_generator_test.rb b/railties/test/generators/assets_generator_test.rb
index a2a40a28d4..375632e5bc 100644
--- a/railties/test/generators/assets_generator_test.rb
+++ b/railties/test/generators/assets_generator_test.rb
@@ -1,32 +1,26 @@
require 'generators/generators_test_helper'
require 'rails/generators/rails/assets/assets_generator'
-# FOXME: Silence the 'Could not find task "using_coffee?"' message in tests due to the public stub
+# FIXME: Silence the 'Could not find task "using_coffee?"' message in tests due to the public stub
class AssetsGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
arguments %w(posts)
- def test_vanilla_assets
+ def test_assets
run_generator
- assert_file "app/assets/javascripts/posts.js"
- assert_file "app/assets/stylesheets/posts.css"
+ assert_file "app/assets/javascripts/posts.js.coffee"
+ assert_file "app/assets/stylesheets/posts.css.scss"
end
def test_skipping_assets
- content = run_generator ["posts", "--skip-assets"]
- assert_no_file "app/assets/javascripts/posts.js"
- assert_no_file "app/assets/stylesheets/posts.css"
- end
-
- def test_coffee_javascript
- self.generator_class.any_instance.stubs(:using_coffee?).returns(true)
- run_generator
- assert_file "app/assets/javascripts/posts.js.coffee"
+ content = run_generator ["posts", "--no-stylesheets", "--no-javascripts"]
+ assert_no_file "app/assets/javascripts/posts.js.coffee"
+ assert_no_file "app/assets/stylesheets/posts.css.scss"
end
- def test_sass_stylesheet
- self.generator_class.any_instance.stubs(:using_sass?).returns(true)
- run_generator
- assert_file "app/assets/stylesheets/posts.css.scss"
+ def test_vanilla_assets
+ run_generator ["posts", "--no-javascript-engine", "--no-stylesheet-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 655d8ad450..2dfc91c683 100644
--- a/railties/test/generators/controller_generator_test.rb
+++ b/railties/test/generators/controller_generator_test.rb
@@ -39,8 +39,8 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
def test_invokes_assets
run_generator
- assert_file "app/assets/javascripts/account.js"
- assert_file "app/assets/stylesheets/account.css"
+ assert_file "app/assets/javascripts/account.js.coffee"
+ assert_file "app/assets/stylesheets/account.css.scss"
end
def test_invokes_default_test_framework
diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb
index d61a02d32f..eb56e8d1a4 100644
--- a/railties/test/generators/namespaced_generators_test.rb
+++ b/railties/test/generators/namespaced_generators_test.rb
@@ -248,7 +248,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
assert_file "test/unit/helpers/test_app/product_lines_helper_test.rb"
# Stylesheets
- assert_file "public/stylesheets/scaffold.css"
+ assert_file "app/assets/stylesheets/scaffold.css.scss"
end
def test_scaffold_on_revoke
@@ -279,7 +279,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
assert_no_file "test/unit/helpers/test_app/product_lines_helper_test.rb"
# Stylesheets (should not be removed)
- assert_file "public/stylesheets/scaffold.css"
+ assert_file "app/assets/stylesheets/scaffold.css.scss"
end
def test_scaffold_with_namespace_on_invoke
@@ -320,7 +320,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
assert_file "test/unit/helpers/test_app/admin/roles_helper_test.rb"
# Stylesheets
- assert_file "public/stylesheets/scaffold.css"
+ assert_file "app/assets/stylesheets/scaffold.css.scss"
end
def test_scaffold_with_namespace_on_revoke
@@ -352,6 +352,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
assert_no_file "test/unit/helpers/test_app/admin/roles_helper_test.rb"
# Stylesheets (should not be removed)
- assert_file "public/stylesheets/scaffold.css"
+ assert_file "app/assets/stylesheets/scaffold.css.scss"
end
end
diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb
index 402fd25b14..fb956a8335 100644
--- a/railties/test/generators/plugin_new_generator_test.rb
+++ b/railties/test/generators/plugin_new_generator_test.rb
@@ -95,32 +95,33 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
def test_skipping_javascripts_without_mountable_option
run_generator
- assert_no_file "public/javascripts/jquery.js"
- assert_no_file "public/javascripts/rails.js"
- assert_no_file "public/javascripts/application.js"
+ assert_no_file "app/assets/javascripts/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 "public/javascripts/jquery.js"
- assert_file "public/javascripts/rails.js"
- assert_file "public/javascripts/application.js"
+ assert_file "app/assets/javascripts/application.js"
+ assert_file "vendor/assets/javascripts/jquery.js"
+ assert_file "vendor/assets/javascripts/jquery_ujs.js"
end
def test_skip_javascripts
run_generator [destination_root, "--skip-javascript", "--mountable"]
- assert_no_file "public/javascripts/jquery.js"
- assert_no_file "public/javascripts/rails.js"
+ assert_no_file "app/assets/javascripts/application.js"
+ assert_no_file "vendor/assets/javascripts/jquery.js"
+ assert_no_file "vendor/assets/javascripts/jquery_ujs.js"
end
- def test_ensure_that_javascript_option_is_passed_to_app_generator
- run_generator [destination_root, "--javascript", "prototype"]
- assert_file "test/dummy/public/javascripts/prototype.js"
- end
-
- def test_ensure_that_skip_javascript_option_is_passed_to_app_generator
- run_generator [destination_root, "--skip_javascript"]
- assert_no_file "test/dummy/public/javascripts/jquery.js"
+ def test_config_prototype_javascript_library
+ run_generator [destination_root, "-j", "prototype", "--mountable"]
+ assert_file "app/assets/javascripts/application.js"
+ assert_file "vendor/assets/javascripts/prototype.js"
+ assert_file "vendor/assets/javascripts/effects.js"
+ assert_file "vendor/assets/javascripts/dragdrop.js"
+ assert_file "vendor/assets/javascripts/controls.js"
+ assert_file "vendor/assets/javascripts/prototype_ujs.js", /prototype/
end
def test_template_from_dir_pwd
@@ -139,11 +140,18 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
run_generator [destination_root, "--full", "--skip_active_record"]
FileUtils.cd destination_root
`bundle install`
- assert_match(/2 tests, 2 assertions, 0 failures, 0 errors/, `bundle exec rake test`)
+ assert_match(/1 tests, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`)
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/models"
+ assert_file "app/controllers"
+ assert_file "app/views"
+ assert_file "app/helpers"
assert_file "config/routes.rb", /Rails.application.routes.draw do/
assert_file "lib/bukkits/engine.rb", /module Bukkits\n class Engine < Rails::Engine\n end\nend/
assert_file "lib/bukkits.rb", /require "bukkits\/engine"/
@@ -155,6 +163,9 @@ 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 "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"/
@@ -218,3 +229,4 @@ protected
silence(:stdout){ generator.send(*args, &block) }
end
end
+
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index df787f61ba..4b07f8bcbe 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -79,8 +79,10 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_file "app/helpers/product_lines_helper.rb"
assert_file "test/unit/helpers/product_lines_helper_test.rb"
- # Stylesheets
- assert_file "public/stylesheets/scaffold.css"
+ # Assets
+ assert_file "app/assets/stylesheets/scaffold.css.scss"
+ assert_file "app/assets/javascripts/product_lines.js.coffee"
+ assert_file "app/assets/stylesheets/product_lines.css.scss"
end
def test_scaffold_on_revoke
@@ -110,8 +112,10 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_no_file "app/helpers/product_lines_helper.rb"
assert_no_file "test/unit/helpers/product_lines_helper_test.rb"
- # Stylesheets (should not be removed)
- assert_file "public/stylesheets/scaffold.css"
+ # Assets
+ assert_file "app/assets/stylesheets/scaffold.css.scss", /&:visited/
+ assert_no_file "app/assets/javascripts/product_lines.js.coffee"
+ assert_no_file "app/assets/stylesheets/product_lines.css.scss"
end
def test_scaffold_with_namespace_on_invoke
@@ -184,8 +188,10 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_file "app/helpers/admin/roles_helper.rb"
assert_file "test/unit/helpers/admin/roles_helper_test.rb"
- # Stylesheets
- assert_file "public/stylesheets/scaffold.css"
+ # Assets
+ assert_file "app/assets/stylesheets/scaffold.css.scss", /&:visited/
+ assert_file "app/assets/javascripts/admin/roles.js.coffee"
+ assert_file "app/assets/stylesheets/admin/roles.css.scss"
end
def test_scaffold_with_namespace_on_revoke
@@ -216,8 +222,10 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_no_file "app/helpers/admin/roles_helper.rb"
assert_no_file "test/unit/helpers/admin/roles_helper_test.rb"
- # Stylesheets (should not be removed)
- assert_file "public/stylesheets/scaffold.css"
+ # Assets
+ assert_file "app/assets/stylesheets/scaffold.css.scss"
+ assert_no_file "app/assets/javascripts/admin/roles.js.coffee"
+ assert_no_file "app/assets/stylesheets/admin/roles.css.scss"
end
def test_scaffold_generator_on_revoke_does_not_mutilate_legacy_map_parameter
@@ -235,6 +243,34 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_file "config/routes.rb", /\.routes\.draw do\s*\|map\|\s*$/
end
+ def test_scaffold_generator_no_assets
+ run_generator [ "posts", "--no-assets" ]
+ assert_file "app/assets/stylesheets/scaffold.css.scss"
+ assert_no_file "app/assets/javascripts/posts.js.coffee"
+ assert_no_file "app/assets/stylesheets/posts.css.scss"
+ end
+
+ def test_scaffold_generator_no_stylesheets
+ run_generator [ "posts", "--no-stylesheets" ]
+ assert_no_file "app/assets/stylesheets/scaffold.css.scss"
+ assert_file "app/assets/javascripts/posts.js.coffee"
+ assert_no_file "app/assets/stylesheets/posts.css.scss"
+ end
+
+ def test_scaffold_generator_no_javascripts
+ run_generator [ "posts", "--no-javascripts" ]
+ assert_file "app/assets/stylesheets/scaffold.css.scss"
+ assert_no_file "app/assets/javascripts/posts.js.coffee"
+ assert_file "app/assets/stylesheets/posts.css.scss"
+ end
+
+ def test_scaffold_generator_no_negines
+ run_generator [ "posts", "--no-javascript-engine", "--no-stylesheet-engine" ]
+ assert_file "app/assets/stylesheets/scaffold.css"
+ assert_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)
diff --git a/railties/test/generators/stylesheets_generator_test.rb b/railties/test/generators/stylesheets_generator_test.rb
deleted file mode 100644
index 4b86cdd1c7..0000000000
--- a/railties/test/generators/stylesheets_generator_test.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require 'generators/generators_test_helper'
-require 'rails/generators/rails/stylesheets/stylesheets_generator'
-
-class StylesheetsGeneratorTest < Rails::Generators::TestCase
- include GeneratorsTestHelper
-
- def test_copy_scss_stylesheet
- self.generator_class.any_instance.stubs(:using_sass?).returns(true)
- run_generator
- assert_file "app/assets/stylesheets/scaffold.css.scss"
- end
-
- def test_copy_css_stylesheet
- run_generator
- assert_file "app/assets/stylesheets/scaffold.css"
- end
-
- def test_stylesheets_are_not_deleted_on_revoke
- run_generator
- run_generator [], :behavior => :revoke
- assert_file "app/assets/stylesheets/scaffold.css"
- end
-end
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index c5b1cb9a80..f2261540ca 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -90,6 +90,7 @@ module TestHelpers
end
module Generation
+ # Build an application by invoking the generator and going through the whole stack.
def build_app(options = {})
FileUtils.rm_rf(app_path)
FileUtils.cp_r(tmp_path('app_template'), app_path)
@@ -115,6 +116,8 @@ module TestHelpers
add_to_config 'config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"; config.session_store :cookie_store, :key => "_myapp_session"; config.active_support.deprecation = :log'
end
+ # Make a very basic app, without creating the whole directory structure.
+ # This is faster and simpler than the method above.
def make_basic_app
require "rails"
require "action_controller/railtie"
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index 20797a2b0c..b3cf9ad449 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -1,8 +1,7 @@
require "isolation/abstract_unit"
require "railties/shared_tests"
-require 'stringio'
-require 'rack/test'
-require 'rack/file'
+require "stringio"
+require "rack/test"
module RailtiesTest
class EngineTest < Test::Unit::TestCase
@@ -188,6 +187,7 @@ module RailtiesTest
end
RUBY
+ require "rack/file"
boot_rails
env = Rack::MockRequest.env_for("/")
@@ -199,194 +199,6 @@ module RailtiesTest
assert_equal Rails.application.routes, env['action_dispatch.routes']
end
- test "it allows to set asset_path" do
- @plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
- class Engine < ::Rails::Engine
- end
- end
- RUBY
-
-
- @plugin.write "config/routes.rb", <<-RUBY
- Bukkits::Engine.routes.draw do
- match "/foo" => "foo#index"
- end
- RUBY
-
- @plugin.write "app/controllers/foo_controller.rb", <<-RUBY
- class FooController < ActionController::Base
- def index
- render :index
- end
- end
- RUBY
-
- @plugin.write "app/views/foo/index.html.erb", <<-ERB
- <%= image_path("foo.png") %>
- <%= javascript_include_tag("foo") %>
- <%= stylesheet_link_tag("foo") %>
- ERB
-
- app_file "config/routes.rb", <<-RUBY
- Rails.application.routes.draw do
- mount Bukkits::Engine => "/bukkits"
- end
- RUBY
-
- add_to_config 'config.asset_path = "/omg%s"'
-
- boot_rails
-
- # should set asset_path with engine name by default
- assert_equal "/bukkits_engine%s", ::Bukkits::Engine.config.asset_path
-
- ::Bukkits::Engine.config.asset_path = "/bukkits%s"
-
- get("/bukkits/foo")
- stripped_body = last_response.body.split("\n").map(&:strip).join
-
- expected = "/omg/bukkits/images/foo.png" +
- "<script src=\"/omg/bukkits/javascripts/foo.js\" type=\"text/javascript\"></script>" +
- "<link href=\"/omg/bukkits/stylesheets/foo.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />"
- assert_equal expected, stripped_body
- end
-
- test "default application's asset_path" do
- @plugin.write "config/routes.rb", <<-RUBY
- Bukkits::Engine.routes.draw do
- match "/foo" => "foo#index"
- end
- RUBY
-
- @plugin.write "app/controllers/foo_controller.rb", <<-RUBY
- class FooController < ActionController::Base
- def index
- render :inline => '<%= image_path("foo.png") %>'
- end
- end
- RUBY
-
- app_file "config/routes.rb", <<-RUBY
- AppTemplate::Application.routes.draw do
- mount Bukkits::Engine => "/bukkits"
- end
- RUBY
-
- boot_rails
-
- get("/bukkits/foo")
- assert_equal "/bukkits/images/foo.png", last_response.body.strip
- end
-
- test "engine's files are served via ActionDispatch::Static" do
- add_to_config "config.serve_static_assets = true"
-
- @plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
- class Engine < ::Rails::Engine
- engine_name :bukkits
- end
- end
- RUBY
-
- @plugin.write "public/bukkits.html", "/bukkits/bukkits.html"
- app_file "public/app.html", "/app.html"
- app_file "public/bukkits/file_from_app.html", "/bukkits/file_from_app.html"
-
- boot_rails
-
- get("/app.html")
- assert_equal File.read(File.join(app_path, "public/app.html")), last_response.body
-
- get("/bukkits/bukkits.html")
- assert_equal File.read(File.join(@plugin.path, "public/bukkits.html")), last_response.body
-
- get("/bukkits/file_from_app.html")
- assert_equal File.read(File.join(app_path, "public/bukkits/file_from_app.html")), last_response.body
- end
-
- test "an applications files are given priority over an engines files when served via ActionDispatch::Static" do
- add_to_config "config.serve_static_assets = true"
-
- @plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
- class Engine < ::Rails::Engine
- engine_name :bukkits
- end
- end
- RUBY
-
- app_file "config/routes.rb", <<-RUBY
- AppTemplate::Application.routes.draw do
- mount Bukkits::Engine => "/bukkits"
- end
- RUBY
-
- @plugin.write "public/bukkits.html", "in engine"
-
- app_file "public/bukkits/bukkits.html", "in app"
-
- boot_rails
-
- get('/bukkits/bukkits.html')
-
- assert_equal 'in app', last_response.body.strip
- end
-
- test "shared engine should include application's helpers and own helpers" do
- app_file "config/routes.rb", <<-RUBY
- AppTemplate::Application.routes.draw do
- match "/foo" => "bukkits/foo#index", :as => "foo"
- match "/foo/show" => "bukkits/foo#show"
- match "/foo/bar" => "bukkits/foo#bar"
- end
- RUBY
-
- app_file "app/helpers/some_helper.rb", <<-RUBY
- module SomeHelper
- def something
- "Something... Something... Something..."
- end
- end
- RUBY
-
- @plugin.write "app/helpers/bar_helper.rb", <<-RUBY
- module BarHelper
- def bar
- "It's a bar."
- end
- end
- RUBY
-
- @plugin.write "app/controllers/bukkits/foo_controller.rb", <<-RUBY
- class Bukkits::FooController < ActionController::Base
- def index
- render :inline => "<%= something %>"
- end
-
- def show
- render :text => foo_path
- end
-
- def bar
- render :inline => "<%= bar %>"
- end
- end
- RUBY
-
- boot_rails
-
- get("/foo")
- assert_equal "Something... Something... Something...", last_response.body
-
- get("/foo/show")
- assert_equal "/foo", last_response.body
-
- get("/foo/bar")
- assert_equal "It's a bar.", last_response.body
- end
-
test "isolated engine should include only its own routes and helpers" do
@plugin.write "lib/bukkits.rb", <<-RUBY
module Bukkits
@@ -772,10 +584,7 @@ module RailtiesTest
assert_equal Bukkits::Engine.instance, Rails::Engine.find(engine_path)
end
- test "ensure that engine properly sets assets directories" do
- add_to_config("config.action_dispatch.show_exceptions = false")
- add_to_config("config.serve_static_assets = true")
-
+ test "gather isolated engine's helpers in Engine#helpers" do
@plugin.write "lib/bukkits.rb", <<-RUBY
module Bukkits
class Engine < ::Rails::Engine
@@ -784,56 +593,40 @@ module RailtiesTest
end
RUBY
- @plugin.write "public/stylesheets/foo.css", ""
- @plugin.write "public/javascripts/foo.js", ""
-
- @plugin.write "app/views/layouts/bukkits/application.html.erb", <<-RUBY
- <%= stylesheet_link_tag :all %>
- <%= javascript_include_tag :all %>
- <%= yield %>
+ app_file "app/helpers/some_helper.rb", <<-RUBY
+ module SomeHelper
+ def foo
+ 'foo'
+ end
+ end
RUBY
- @plugin.write "app/controllers/bukkits/home_controller.rb", <<-RUBY
+ @plugin.write "app/helpers/bukkits/engine_helper.rb", <<-RUBY
module Bukkits
- class HomeController < ActionController::Base
- def index
- render :text => "Good morning!", :layout => "bukkits/application"
+ module EngineHelper
+ def bar
+ 'bar'
end
end
end
RUBY
- @plugin.write "config/routes.rb", <<-RUBY
- Bukkits::Engine.routes.draw do
- match "/home" => "home#index"
- end
- RUBY
-
- app_file "config/routes.rb", <<-RUBY
- Rails.application.routes.draw do
- mount Bukkits::Engine => "/bukkits"
+ @plugin.write "app/helpers/engine_helper.rb", <<-RUBY
+ module EngineHelper
+ def baz
+ 'baz'
+ end
end
RUBY
- require 'rack/test'
- extend Rack::Test::Methods
+ add_to_config("config.action_dispatch.show_exceptions = false")
boot_rails
-
require "#{rails_root}/config/environment"
- assert_equal File.join(@plugin.path, "public"), Bukkits::HomeController.assets_dir
- assert_equal File.join(@plugin.path, "public/stylesheets"), Bukkits::HomeController.stylesheets_dir
- assert_equal File.join(@plugin.path, "public/javascripts"), Bukkits::HomeController.javascripts_dir
-
- assert_equal File.join(app_path, "public"), ActionController::Base.assets_dir
- assert_equal File.join(app_path, "public/stylesheets"), ActionController::Base.stylesheets_dir
- assert_equal File.join(app_path, "public/javascripts"), ActionController::Base.javascripts_dir
-
- get "/bukkits/home"
-
- assert_match %r{bukkits/stylesheets/foo.css}, last_response.body
- assert_match %r{bukkits/javascripts/foo.js}, last_response.body
+ methods = Bukkits::Engine.helpers.public_instance_methods.sort
+ expected = ["bar", "baz"]
+ assert_equal expected, methods
end
private
diff --git a/railties/test/railties/shared_tests.rb b/railties/test/railties/shared_tests.rb
index 3eb79d57c8..e975950b85 100644
--- a/railties/test/railties/shared_tests.rb
+++ b/railties/test/railties/shared_tests.rb
@@ -10,42 +10,16 @@ module RailtiesTest
@app ||= Rails.application
end
- def test_install_migrations_and_assets
- @plugin.write "public/javascripts/foo.js", "doSomething()"
+ def test_serving_sprockets_assets
+ @plugin.write "app/assets/javascripts/engine.js.erb", "<%= :alert %>();"
- @plugin.write "db/migrate/1_create_users.rb", <<-RUBY
- class CreateUsers < ActiveRecord::Migration
- end
- RUBY
-
- app_file "db/migrate/1_create_sessions.rb", <<-RUBY
- class CreateSessions < ActiveRecord::Migration
- end
- RUBY
-
- add_to_config "ActiveRecord::Base.timestamped_migrations = false"
-
- Dir.chdir(app_path) do
- `rake bukkits:install`
- assert File.exists?("#{app_path}/db/migrate/2_create_users.rb")
- assert File.exists?(app_path("public/bukkits/javascripts/foo.js"))
- end
- end
-
- def test_copying_assets
- @plugin.write "public/javascripts/foo.js", "doSomething()"
- @plugin.write "public/stylesheets/foo.css", "h1 { font-size: 10000px }"
- @plugin.write "public/images/img.png", ""
-
- Dir.chdir(app_path) do
- `rake bukkits:install:assets --trace`
+ boot_rails
+ require 'rack/test'
+ require 'coffee_script'
+ extend Rack::Test::Methods
- assert File.exists?(app_path("public/bukkits/javascripts/foo.js"))
- assert_equal "doSomething()\n", File.read(app_path("public/bukkits/javascripts/foo.js"))
- assert File.exists?(app_path("public/bukkits/stylesheets/foo.css"))
- assert_equal "h1 { font-size: 10000px }\n", File.read(app_path("public/bukkits/stylesheets/foo.css"))
- assert File.exists?(app_path("public/bukkits/images/img.png"))
- end
+ get "/assets/engine.js"
+ assert_match "alert();", last_response.body
end
def test_copying_migrations