diff options
author | Gonçalo Silva <goncalossilva@gmail.com> | 2011-04-17 17:08:49 +0100 |
---|---|---|
committer | Gonçalo Silva <goncalossilva@gmail.com> | 2011-04-17 17:08:49 +0100 |
commit | 1c2b2233c3a7ec76c0a0eddf5b8be45c489be133 (patch) | |
tree | 56f2b767c3a4f1f14c51606bf2cbb714a98c5f89 /railties | |
parent | 8d558cb1b069410c8f693295c9c4e2ffc9661e06 (diff) | |
parent | b6843f22ac42b503f6b8ac00105ca0679049be7d (diff) | |
download | rails-1c2b2233c3a7ec76c0a0eddf5b8be45c489be133.tar.gz rails-1c2b2233c3a7ec76c0a0eddf5b8be45c489be133.tar.bz2 rails-1c2b2233c3a7ec76c0a0eddf5b8be45c489be133.zip |
Merge branch 'master' of https://github.com/rails/rails into performance_test
Diffstat (limited to 'railties')
90 files changed, 820 insertions, 922 deletions
diff --git a/railties/CHANGELOG b/railties/CHANGELOG index f159247308..a4f0d31971 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,5 +1,25 @@ *Rails 3.1.0 (unreleased)* +* The scaffold controller will now produce SCSS file if Sass is available [Prem Sichanugrist] + +* The controller and resource generators will now automatically produce asset stubs (this can be turned off with --skip-assets). These stubs will use Coffee and Sass, if those libraries are available. [DHH] + +* jQuery is the new default JavaScript library. [fxn] + +* Changed scaffold and app generator to create Ruby 1.9 style hash when running on Ruby 1.9 [Prem Sichanugrist] + + So instead of creating something like: + + redirect_to users_path, :notice => "User has been created" + + it will now be like this: + + redirect_to users_path, notice: "User has been created" + + You can also passing `--old-style-hash` to make Rails generate old style hash even you're on Ruby 1.9 + +* Changed scaffold_controller generator to create format block for JSON instead of XML [Prem Sichanugrist] + * Add using Turn with natural language test case names for test_help.rb when running with minitest (Ruby 1.9.2+) [DHH] * Direct logging of Active Record to STDOUT so it's shown inline with the results in the console [DHH] diff --git a/railties/guides/rails_guides/textile_extensions.rb b/railties/guides/rails_guides/textile_extensions.rb index affef1ccb0..352c5e91dd 100644 --- a/railties/guides/rails_guides/textile_extensions.rb +++ b/railties/guides/rails_guides/textile_extensions.rb @@ -1,9 +1,11 @@ +require 'active_support/core_ext/object/inclusion' + module RailsGuides module TextileExtensions def notestuff(body) body.gsub!(/^(IMPORTANT|CAUTION|WARNING|NOTE|INFO)[.:](.*)$/) do |m| css_class = $1.downcase - css_class = 'warning' if ['caution', 'important'].include?(css_class) + css_class = 'warning' if css_class.in?(['caution', 'important']) result = "<div class='#{css_class}'><p>" result << $2.strip @@ -33,7 +35,7 @@ module RailsGuides def code(body) body.gsub!(%r{<(yaml|shell|ruby|erb|html|sql|plain)>(.*?)</\1>}m) do |m| es = ERB::Util.h($2) - css_class = ['erb', 'shell'].include?($1) ? 'html' : $1 + css_class = $1.in?(['erb', 'shell']) ? 'html' : $1 %{<notextile><div class="code_container"><code class="#{css_class}">#{es}</code></div></notextile>} end end diff --git a/railties/guides/source/2_3_release_notes.textile b/railties/guides/source/2_3_release_notes.textile index 67743a4797..15abba66ab 100644 --- a/railties/guides/source/2_3_release_notes.textile +++ b/railties/guides/source/2_3_release_notes.textile @@ -410,7 +410,7 @@ You're likely familiar with Rails' practice of adding timestamps to static asset h4. Asset Hosts as Objects -Asset hosts get more flexible in edge Rails with the ability to declare an asset host as a specific object that responds to a call. This allows you to to implement any complex logic you need in your asset hosting. +Asset hosts get more flexible in edge Rails with the ability to declare an asset host as a specific object that responds to a call. This allows you to implement any complex logic you need in your asset hosting. * More Information: "asset-hosting-with-minimum-ssl":http://github.com/dhh/asset-hosting-with-minimum-ssl/tree/master diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile index 178d98c2d6..496dc7224b 100644 --- a/railties/guides/source/action_controller_overview.textile +++ b/railties/guides/source/action_controller_overview.textile @@ -615,26 +615,15 @@ Rails comes with two built-in HTTP authentication mechanisms: h4. HTTP Basic Authentication -HTTP basic authentication is an authentication scheme that is supported by the majority of browsers and other HTTP clients. As an example, consider an administration section which will only be available by entering a username and a password into the browser's HTTP basic dialog window. Using the built-in authentication is quite easy and only requires you to use one method, +authenticate_or_request_with_http_basic+. +HTTP basic authentication is an authentication scheme that is supported by the majority of browsers and other HTTP clients. As an example, consider an administration section which will only be available by entering a username and a password into the browser's HTTP basic dialog window. Using the built-in authentication is quite easy and only requires you to use one method, +http_basic_authenticate_with+. <ruby> class AdminController < ApplicationController - USERNAME, PASSWORD = "humbaba", "5baa61e4" - - before_filter :authenticate - - private - - def authenticate - authenticate_or_request_with_http_basic do |username, password| - username == USERNAME && - Digest::SHA1.hexdigest(password) == PASSWORD - end - end + http_basic_authenticate_with :name => "humbaba", :password => "5baa61e4" end </ruby> -With this in place, you can create namespaced controllers that inherit from +AdminController+. The before filter will thus be run for all actions in those controllers, protecting them with HTTP basic authentication. +With this in place, you can create namespaced controllers that inherit from +AdminController+. The filter will thus be run for all actions in those controllers, protecting them with HTTP basic authentication. h4. HTTP Digest Authentication diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile index cfd71ad287..d0b3ee6bfc 100644 --- a/railties/guides/source/action_view_overview.textile +++ b/railties/guides/source/action_view_overview.textile @@ -1295,7 +1295,7 @@ end h5. update_page_tag -Works like update_page but wraps the generated JavaScript in a +script+ tag. Use this to include generated JavaScript in an ERb template. +Works like update_page but wraps the generated JavaScript in a +script+ tag. Use this to include generated JavaScript in an ERB template. h4. PrototypeHelper::JavaScriptGenerator::GeneratorMethods diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile index f3a10b8b92..df8e35ed33 100644 --- a/railties/guides/source/active_record_querying.textile +++ b/railties/guides/source/active_record_querying.textile @@ -790,7 +790,7 @@ Post.includes(:comments).where("comments.visible", true) This would generate a query which contains a +LEFT OUTER JOIN+ whereas the +joins+ method would generate one using the +INNER JOIN+ function instead. <ruby> - SELECT "posts"."id" AS t0_r0, ... "comments"."updated_at" AS t1_r5 FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (comments.visible) + SELECT "posts"."id" AS t0_r0, ... "comments"."updated_at" AS t1_r5 FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (comments.visible = 1) </ruby> If there was no +where+ condition, this would generate the normal set of two queries. diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile index 514d0322b9..c65dd52e48 100644 --- a/railties/guides/source/active_record_validations_callbacks.textile +++ b/railties/guides/source/active_record_validations_callbacks.textile @@ -822,7 +822,7 @@ The selectors to customize the style of error messages are: * +#errorExplanation p+ - Style for the paragraph that holds the message that appears right below the header of the +div+ element. * +#errorExplanation ul li+ - Style for the list items with individual error messages. -Scaffolding for example generates +public/stylesheets/scaffold.css+, which defines the red-based style you saw above. +Scaffolding for example generates +app/assets/stylesheets/scaffold.css.scss+, which later compiles to +app/assets/stylesheets/scaffold.css+ and defines the red-based style you saw above. The name of the class and the id can be changed with the +:class+ and +:id+ options, accepted by both helpers. diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 788f528654..3ba840c044 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -442,6 +442,28 @@ require_library_or_gem('mysql') NOTE: Defined in +active_support/core_ext/kernel/requires.rb+. +h4. +in?+ and +either?+ + +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. + +Examples of +in?+: + +<ruby> + 1.in?([1,2]) # => true + "lo".in?("hello") # => true + 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+ h4. +alias_method_chain+ diff --git a/railties/guides/source/ajax_on_rails.textile b/railties/guides/source/ajax_on_rails.textile index b80df4aa58..38a63ea483 100644 --- a/railties/guides/source/ajax_on_rails.textile +++ b/railties/guides/source/ajax_on_rails.textile @@ -3,14 +3,14 @@ h2. AJAX on Rails This guide covers the built-in Ajax/JavaScript functionality of Rails (and more); it will enable you to create rich and dynamic AJAX applications with ease! We will cover the following topics: * Quick introduction to AJAX and related technologies -* Handling JavaScript the Rails way: Rails helpers, RJS, Prototype and script.aculo.us +* Handling JavaScript the Rails way: Rails helpers, Prototype and script.aculo.us * Testing JavaScript functionality endprologue. h3. Hello AJAX - a Quick Intro -If you are a 'show me the code' type of person, you might want to skip this part and jump to the RJS section right away. However, I would really recommend to read it - you'll need the basics of DOM, http requests and other topics discussed here to really understand Ajax on Rails. +You'll need the basics of DOM, HTTP requests and other topics discussed here to really understand Ajax on Rails. h4. Asynchronous JavaScript + XML @@ -62,7 +62,7 @@ link_to_remote "Add to cart", * The second parameter, the +options+ hash is the most interesting part as it has the AJAX specific stuff: ** *:url* This is the only parameter that is always required to generate the simplest remote link (technically speaking, it is not required, you can pass an empty +options+ hash to +link_to_remote+ - but in this case the URL used for the POST request will be equal to your current URL which is probably not your intention). This URL points to your AJAX action handler. The URL is typically specified by Rails REST view helpers, but you can use the +url_for+ format too. -** *:update* There are basically two ways of injecting the server response into the page: One is involving RJS and we will discuss it in the next chapter, and the other is specifying a DOM id of the element we would like to update. The above example demonstrates the simplest way of accomplishing this - however, we are in trouble if the server responds with an error message because that will be injected into the page too! However, Rails has a solution for this situation: +** *:update* Specifying a DOM id of the element we would like to update. The above example demonstrates the simplest way of accomplishing this - however, we are in trouble if the server responds with an error message because that will be injected into the page too! However, Rails has a solution for this situation: <ruby> link_to_remote "Add to cart", @@ -178,12 +178,7 @@ h5. +remote_function+ h5. +update_page+ - -h3. JavaScript the Rails way: RJS - -In the last section we sent some AJAX requests to the server, and inserted the HTML response into the page (with the +:update+ option). However, sometimes a more complicated interaction with the page is needed, which you can either achieve with JavaScript... or with RJS! You are sending JavaScript instructions to the server in both cases, but while in the former case you have to write vanilla JavaScript, in the second you can code Rails, and sit back while Rails generates the JavaScript for you - so basically RJS is a Ruby DSL to write JavaScript in your Rails code. - -h4. JavaScript without RJS +h4. Serving JavaScript First we'll check out how to send JavaScript to the server manually. You are practically never going to need this, but it's interesting to understand what's going on under the hood. @@ -198,136 +193,6 @@ end What happens here is that by specifying the Content-Type header variable, we instruct the browser to evaluate the text we are sending over (rather than displaying it as plain text, which is the default behavior). -h4. Inline RJS - -As we said, the purpose of RJS is to write Ruby which is then auto-magically turned into JavaScript by Rails. The above example didn't look too Ruby-esque so let's see how to do it the Rails way: - -<ruby> -def javascript_test - render :update do |page| - page.alert "Hello from inline RJS" - end -end -</ruby> - -The above code snippet does exactly the same as the one in the previous section - going about it much more elegantly though. You don't need to worry about headers,write ugly JavaScript code into a string etc. When the first parameter to +render+ is +:update+, Rails expects a block with a single parameter (+page+ in our case, which is the traditional naming convention) which is an instance of the JavaScriptGenerator:"http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/GeneratorMethods.html" object. As it's name suggests, JavaScriptGenerator is responsible for generating JavaScript from your Ruby code. You can execute multiple method calls on the +page+ instance - it's all turned into JavaScript code and sent to the server with the appropriate Content Type, "text/javascript". - -h4. RJS Templates - -If you don't want to clutter your controllers with view code (especially when your inline RJS is more than a few lines), you can move your RJS code to a template file. RJS templates should go to the +/app/views/+ directory, just as +.html.erb+ or any other view files of the appropriate controller, conventionally named +js.rjs+. - -To rewrite the above example, you can leave the body of the action empty, and create a RJS template named +javascript_test.js.rjs+, containing the following line: - -<ruby> -page.alert "Hello from inline RJS" -</ruby> - -h4. RJS Reference - -In this section we'll go through the methods RJS offers. - -h5. JavaScriptGenerator Methods - -h6. DOM Element Manipulation - -It is possible to manipulate multiple elements at once through the +page+ JavaScriptGenerator instance. Let's see this in action: - -<ruby> -page.show :div_one, :div_two -page.hide :div_one -page.remove :div_one, :div_two, :div_three -page.toggle :other_div -</ruby> - -The above methods (+show+, +hide+, +remove+, +toggle+) have the same semantics as the Prototype methods of the same name. You can pass an arbitrary number (but at least one) of DOM ids to these calls. - - -h6. Inserting and Replacing Content - -You can insert content into an element on the page with the +insert_html+ method: - -<ruby> -page.insert_html :top, :result, '42' -</ruby> - -The first parameter is the position of the new content relative to the element specified by the second parameter, a DOM id. - -Position can be one of these four values: - -*** +:before+ Inserts the response text just before the target element. -*** +:after+ The response is inserted after the target element. -*** +:top+ Inserts the text into the target element, before it's original content. -*** +:bottom+ The counterpart of +:top+: the response is inserted after the target element's original content. - -The third parameter can either be a string, or a hash of options to be passed to ActionView::Base#render - for example: - -<ruby> -page.insert_html :top, :result, :partial => "the_answer" -</ruby> - -You can replace the contents (innerHTML) of an element with the +replace_html+ method. The only difference is that since it's clear where should the new content go, there is no need for a position parameter - so +replace_html+ takes only two arguments, -the DOM id of the element you wish to modify and a string or a hash of options to be passed to ActionView::Base#render. - -h6. Delay - -You can delay the execution of a block of code with +delay+: - -<ruby> -page.delay(10) { page.alert('Hey! Just waited 10 seconds') } -</ruby> - -+delay+ takes one parameter (time to wait in seconds) and a block which will be executed after the specified time has passed - whatever else follows a +page.delay+ line is executed immediately, the delay affects only the code in the block. - -h6. Reloading and Redirecting - -You can reload the page with the +reload+ method: - -<ruby> -page.reload -</ruby> - -When using AJAX, you can't rely on the standard +redirect_to+ controller method - you have to use the +page+'s instance method, also called +redirect_to+: - -<ruby> -page.redirect_to some_url -</ruby> - -h6. Generating Arbitrary JavaScript - -Sometimes even the full power of RJS is not enough to accomplish everything, but you still don't want to drop to pure JavaScript. A nice golden mean is offered by the combination of +<<+, +assign+ and +call+ methods: - -<ruby> - page << "alert('1+1 equals 3')" -</ruby> - -So +<<+ is used to execute an arbitrary JavaScript statement, passed as string to the method. The above code is equivalent to: - -<ruby> - page.assign :result, 3 - page.call :alert, '1+1 equals ' + result -</ruby> - -+assign+ simply assigns a value to a variable. +call+ is similar to +<<+ with a slightly different syntax: the first parameter is the name of the function to call, followed by the list of parameters passed to the function. - -h6. Class Proxies - -h5. Element Proxies - -h5. Collection Proxies - -h5. RJS Helpers - - - -h3. I Want my Yellow Thingy: Quick overview of Script.aculo.us - -h4. Introduction - -h4. Visual Effects - -h4. Drag and Drop - - h3. Testing JavaScript diff --git a/railties/guides/source/api_documentation_guidelines.textile b/railties/guides/source/api_documentation_guidelines.textile index 7433507866..e22ffa4c04 100644 --- a/railties/guides/source/api_documentation_guidelines.textile +++ b/railties/guides/source/api_documentation_guidelines.textile @@ -29,7 +29,7 @@ Documentation has to be concise but comprehensive. Explore and document edge cas The proper names of Rails components have a space in between the words, like "Active Support". +ActiveRecord+ is a Ruby module, whereas Active Record is an ORM. All Rails documentation should consistently refer to Rails components by their proper name, and if in your next blog post or presentation you remember this tidbit and take it into account that'd be phenomenal. -Spell names correctly: Arel, Test::Unit, RSpec, HTML, MySQL, JavaScript, ERb. When in doubt, please have a look at some authoritative source like their official documentation. +Spell names correctly: Arel, Test::Unit, RSpec, HTML, MySQL, JavaScript, ERB. When in doubt, please have a look at some authoritative source like their official documentation. Use the article "an" for "SQL", as in "an SQL statement". Also "an SQLite database". diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile index 581fece1ab..9d8a9caf08 100644 --- a/railties/guides/source/command_line.textile +++ b/railties/guides/source/command_line.textile @@ -215,13 +215,13 @@ $ rails generate scaffold HighScore game:string score:integer create app/views/layouts/ exists test/functional/ create test/unit/ - create public/stylesheets/ + create app/assets/stylesheets/ create app/views/high_scores/index.html.erb create app/views/high_scores/show.html.erb create app/views/high_scores/new.html.erb create app/views/high_scores/edit.html.erb create app/views/layouts/high_scores.html.erb - create public/stylesheets/scaffold.css + create app/assets/stylesheets/scaffold.css.scss create app/controllers/high_scores_controller.rb create test/functional/high_scores_controller_test.rb create app/helpers/high_scores_helper.rb @@ -484,7 +484,7 @@ end We take whatever args are supplied, save them to an instance variable, and literally copying from the Rails source, implement a +manifest+ method, which calls +record+ with a block, and we: * Check there's a *public* directory. You bet there is. -* Run the ERb template called "tutorial.erb". +* Run the ERB template called "tutorial.erb". * Save it into "Rails.root/public/tutorial.txt". * Pass in the arguments we saved through the +:assigns+ parameter. diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile index 298335d484..53460b8c36 100644 --- a/railties/guides/source/configuring.textile +++ b/railties/guides/source/configuring.textile @@ -149,7 +149,7 @@ h4. Configuring Middleware Every Rails application comes with a standard set of middleware which it uses in this order in the development environment: -* +Rack::SSL+ Will force every requests to be under HTTPS protocol. Will be available if +config.force_ssl+ is set to _true_. +* +Rack::SSL+ Will force every request to be under HTTPS protocol. Will be available if +config.force_ssl+ is set to _true_. * +ActionDispatch::Static+ is used to serve static assets. Disabled if +config.serve_static_assets+ is _true_. * +Rack::Lock+ Will wrap the app in mutex so it can only be called by a single thread at a time. Only enabled if +config.action_controller.allow_concurrency+ is set to _false_, which it is by default. * +ActiveSupport::Cache::Strategy::LocalCache+ Serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread. @@ -291,8 +291,6 @@ h4. Configuring Action View There are only a few configuration options for Action View, starting with four on +ActionView::Base+: -* +config.action_view.debug_rjs+ specifies whether RJS responses should be wrapped in a try/catch block that alerts the caught exception (and then re-raises it). The default is +false+. - * +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| %Q(%<div class="field_with_errors">#{html_tag}</div>).html_safe }</tt> * +config.action_view.default_form_builder+ tells Rails which form builder to use by default. The default is +ActionView::Helpers::FormBuilder+. diff --git a/railties/guides/source/debugging_rails_applications.textile b/railties/guides/source/debugging_rails_applications.textile index 045b8823ca..fb17dccfb8 100644 --- a/railties/guides/source/debugging_rails_applications.textile +++ b/railties/guides/source/debugging_rails_applications.textile @@ -96,26 +96,6 @@ Will be rendered as follows: Title: Rails debugging guide </pre> -h4. Debugging RJS - -Rails has optional built-in support to debug RJS. When enabled, responses are wrapped in a try/catch block that displays the caught exception using +alert()+, and then re-raises it. - -The flag to enable RJS debugging in your configuration files is +config.action_view.debug_rjs+: - -<ruby> -config.action_view.debug_rjs = true -</ruby> - -or at any time setting +ActionView::Base.debug_rjs+: - -<ruby> -ActionView::Base.debug_rjs = true -</ruby> - -It is enabled by default in development mode, and disabled in the rest. - -TIP: For more information on debugging JavaScript, refer to "Firebug":http://getfirebug.com/, the popular debugger for Firefox. - h3. The Logger It can also be useful to save information to log files at runtime. Rails maintains a separate log file for each runtime environment. diff --git a/railties/guides/source/generators.textile b/railties/guides/source/generators.textile index d32ba48003..cd8ac3d6fd 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 public/stylesheets/scaffold.css + create app/assets/stylesheets/scaffold.css.scss </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. diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 0661549644..3f9bd2b6da 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -368,7 +368,7 @@ The scaffold generator will build 15 files in your application, along with some |test/functional/posts_controller_test.rb |Functional testing harness for the posts controller| |test/unit/helpers/posts_helper_test.rb |Unit testing harness for the posts helper| |config/routes.rb |Edited to include routing information for posts| -|public/stylesheets/scaffold.css |Cascading style sheet to make the scaffolded views look better| +|app/assets/stylesheets/scaffold.css.scss |Cascading style sheet to make the scaffolded views look better| h4. Running a Migration @@ -501,8 +501,8 @@ def index @posts = Post.all respond_to do |format| - format.html # index.html.erb - format.xml { render :xml => @posts } + format.html # index.html.erb + format.json { render :json => @posts } end end </ruby> @@ -511,7 +511,7 @@ end TIP: For more information on finding records with Active Record, see "Active Record Query Interface":active_record_querying.html. -The +respond_to+ block handles both HTML and XML calls to this action. If you browse to "http://localhost:3000/posts.xml":http://localhost:3000/posts.xml, you'll see all of the posts in XML format. The HTML format looks for a view in +app/views/posts/+ with a name that corresponds to the action name. Rails makes all of the instance variables from the action available to the view. Here's +app/views/posts/index.html.erb+: +The +respond_to+ block handles both HTML and JSON calls to this action. If you browse to "http://localhost:3000/posts.json":http://localhost:3000/posts.json, you'll see a JSON containing all of the posts. The HTML format looks for a view in +app/views/posts/+ with a name that corresponds to the action name. Rails makes all of the instance variables from the action available to the view. Here's +app/views/posts/index.html.erb+: <erb> <h1>Listing posts</h1> @@ -584,8 +584,8 @@ def new @post = Post.new respond_to do |format| - format.html # new.html.erb - format.xml { render :xml => @post } + format.html # new.html.erb + format.json { render :json => @post } end end </ruby> @@ -653,13 +653,13 @@ def create respond_to do |format| if @post.save - format.html { redirect_to(@post, + format.html { redirect_to(@post, :notice => 'Post was successfully created.') } - format.xml { render :xml => @post, + format.json { render :json => @post, :status => :created, :location => @post } else - format.html { render :action => "new" } - format.xml { render :xml => @post.errors, + format.html { render :action => "new" } + format.json { render :json => @post.errors, :status => :unprocessable_entity } end end @@ -681,8 +681,8 @@ def show @post = Post.find(params[:id]) respond_to do |format| - format.html # show.html.erb - format.xml { render :xml => @post } + format.html # show.html.erb + format.json { render :json => @post } end end </ruby> @@ -743,12 +743,12 @@ def update respond_to do |format| if @post.update_attributes(params[:post]) - format.html { redirect_to(@post, + format.html { redirect_to(@post, :notice => 'Post was successfully updated.') } - format.xml { head :ok } + format.json { render :json => {}, :status => :ok } else - format.html { render :action => "edit" } - format.xml { render :xml => @post.errors, + format.html { render :action => "edit" } + format.json { render :json => @post.errors, :status => :unprocessable_entity } end end @@ -767,8 +767,8 @@ def destroy @post.destroy respond_to do |format| - format.html { redirect_to(posts_url) } - format.xml { head :ok } + format.html { redirect_to(posts_url) } + format.json { render :json => {}, :status => :ok } end end </ruby> @@ -1201,36 +1201,19 @@ h3. Security If you were to publish your blog online, anybody would be able to add, edit and delete posts or delete comments. -Rails provides a very simple HTTP authentication system that will work nicely in this situation. First, we enable simple HTTP based authentication in our <tt>app/controllers/application_controller.rb</tt>: +Rails provides a very simple HTTP authentication system that will work nicely in this situation. -<ruby> -class ApplicationController < ActionController::Base - protect_from_forgery - - private - - def authenticate - authenticate_or_request_with_http_basic do |user_name, password| - user_name == 'admin' && password == 'password' - end - end - -end -</ruby> - -You can obviously change the username and password to whatever you want. We put this method inside of +ApplicationController+ so that it is available to all of our controllers. - -Then in the +PostsController+ we need to have a way to block access to the various actions if the person is not authenticated, here we can use the Rails <tt>before_filter</tt> method, which allows us to specify that Rails must run a method and only then allow access to the requested action if that method allows it. +In the +PostsController+ we need to have a way to block access to the various actions if the person is not authenticated, here we can use the Rails <tt>http_basic_authenticate_with</tt> method, allowing access to the requested action if that method allows it. -To use the before filter, we specify it at the top of our +PostsController+, in this case, we want the user to be authenticated on every action, except for +index+ and +show+, so we write that: +To use the authentication system, we specify it at the top of our +PostsController+, in this case, we want the user to be authenticated on every action, except for +index+ and +show+, so we write that: <ruby> class PostsController < ApplicationController - before_filter :authenticate, :except => [:index, :show] + http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index # GET /posts - # GET /posts.xml + # GET /posts.json def index @posts = Post.all respond_to do |format| @@ -1242,7 +1225,7 @@ We also only want to allow authenticated users to delete comments, so in the +Co <ruby> class CommentsController < ApplicationController - before_filter :authenticate, :only => :destroy + http_basic_authenticate_with :name => "dhh", :password => "secret", :only => :destroy def create @post = Post.find(params[:post_id]) @@ -1475,6 +1458,7 @@ Two very common sources of data that are not UTF-8: h3. Changelog +* April 11, 2011: Changed scaffold_controller generator to create format block for JSON instead of XML "Sebastian Martinez":http://www.wyeworks.com * August 30, 2010: Minor editing after Rails 3 release by "Joost Baaij":http://www.spacebabies.nl * July 12, 2010: Fixes, editing and updating of code samples by "Jaime Iniesta":http://jaimeiniesta.com * May 16, 2010: Added a section on configuration gotchas to address common encoding problems that people might have by "Yehuda Katz":http://www.yehudakatz.com diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index 0cbbe1f389..7c01f01b24 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -478,8 +478,7 @@ The next line in +config/application.rb+ is: require 'rails/all' </ruby> -h4 +railties/lib/rails/all.rb+ - +h4. +railties/lib/rails/all.rb+ This file is responsible for requiring all the individual parts of Rails like so: @@ -591,7 +590,7 @@ h4. +activesupport/lib/active_support/deprecation/behaviors.rb+ This file defines the behavior of the +ActiveSupport::Deprecation+ module, setting up the +DEFAULT_BEHAVIORS+ hash constant which contains the three defaults to outputting deprecation warnings: +:stderr+, +:log+ and +:notify+. This file begins by requiring +activesupport/notifications+ and +activesupport/core_ext/array/wrap+. -h4 +activesupport/lib/active_support/notifications.rb+ +h4. +activesupport/lib/active_support/notifications.rb+ TODO: document +ActiveSupport::Notifications+. diff --git a/railties/guides/source/layout.html.erb b/railties/guides/source/layout.html.erb index f2681c6461..911655e0f4 100644 --- a/railties/guides/source/layout.html.erb +++ b/railties/guides/source/layout.html.erb @@ -111,7 +111,7 @@ <h3>Feedback</h3> <p> - You're encouraged to help in keeping the quality of this guide. + You're encouraged to help improve the quality of this guide. </p> <p> If you see any typos or factual errors you are confident to diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index 1548da0eb5..8dab578e6b 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -90,7 +90,7 @@ If we want to display the properties of all the books in our view, we can do so <%= link_to 'New book', new_book_path %> </ruby> -NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandlers+. This guide does not dig into that process, but it's important to know that the file extension on your view controls the choice of template handler. In Rails 2, the standard extensions are +.erb+ for ERB (HTML with embedded Ruby), +.rjs+ for RJS (JavaScript with embedded ruby) and +.builder+ for Builder (XML generator). +NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandlers+. This guide does not dig into that process, but it's important to know that the file extension on your view controls the choice of template handler. In Rails 2, the standard extensions are +.erb+ for ERB (HTML with embedded Ruby), and +.builder+ for Builder (XML generator). h4. Using +render+ @@ -250,18 +250,6 @@ render :inline => "xml.p {'Horrid coding practice!'}", :type => :builder </ruby> -h5. Using +render+ with +:update+ - -You can also render JavaScript-based page updates inline using the +:update+ option to +render+: - -<ruby> -render :update do |page| - page.replace_html 'warning', "Invalid options supplied" -end -</ruby> - -WARNING: Placing JavaScript updates in your controller may seem to streamline small updates, but it defeats the MVC orientation of Rails and will make it harder for other developers to follow the logic of your project. We recommend using a separate RJS template instead, no matter how small the update. - h5. Rendering Text You can send plain text - with no markup at all - back to the browser by using the +:text+ option to +render+: @@ -296,7 +284,7 @@ TIP: You don't need to call +to_xml+ on the object that you want to render. If y h5. Rendering Vanilla JavaScript -Rails can render vanilla JavaScript (as an alternative to using +update+ with an +.rjs+ file): +Rails can render vanilla JavaScript: <ruby> render :js => "alert('Hello Rails');" @@ -707,18 +695,28 @@ To include +http://example.com/main.js+: <%= javascript_include_tag "http://example.com/main.js" %> </erb> -The +defaults+ option loads the Prototype and Scriptaculous libraries: +The +:defaults+ option loads jQuery by default: <erb> <%= javascript_include_tag :defaults %> </erb> -The +all+ option loads every JavaScript file in +public/javascripts+, starting with the Prototype and Scriptaculous libraries: +If the application was generated with "-j prototype" <tt>:defaults</tt> loads Prototype and Scriptaculous. And you can in any case override the expansion in <tt>config/application.rb</tt>: + +<ruby> +config.action_view.javascript_expansions[:defaults] = %w(foo.js bar.js) +</ruby> + +When using <tt>:defaults</tt>, if an <tt>application.js</tt> file exists in <tt>public/javascripts</tt> it will be included as well at then end. + +The +:all+ option loads every JavaScript file in +public/javascripts+: <erb> <%= javascript_include_tag :all %> </erb> +Note that your defaults of choice will be included first, so they will be available to all subsequently included files. + You can supply the +:recursive+ option to load files in subfolders of +public/javascripts+ as well: <erb> diff --git a/railties/guides/source/ruby_on_rails_guides_guidelines.textile b/railties/guides/source/ruby_on_rails_guides_guidelines.textile index 6576758856..8e55780dca 100644 --- a/railties/guides/source/ruby_on_rails_guides_guidelines.textile +++ b/railties/guides/source/ruby_on_rails_guides_guidelines.textile @@ -10,10 +10,10 @@ Guides are written in "Textile":http://www.textism.com/tools/textile/. There's c 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 readers what's the guide about, and what will they learn. See for example the "Routing Guide":routing.html. +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: @@ -23,7 +23,7 @@ h5. Middleware Stack is an Array h5. When are Objects Saved? </plain> -Use same typography as in regular text: +Use the same typography as in regular text: <plain> h6. The +:content_type+ Option @@ -42,13 +42,13 @@ Those guidelines apply also to guides. h3. HTML Generation -To generate all the guides just cd into the +railties+ directory and execute +To generate all the guides, just +cd+ into the +railties+ directory and execute: <plain> bundle exec rake generate_guides </plain> -You'll need the gems erubis, i18n, and RedCloth. +(You may need to run +bundle install+ first to install the required gems.) To process +my_guide.textile+ and nothing else use the +ONLY+ environment variable: @@ -56,13 +56,13 @@ To process +my_guide.textile+ and nothing else use the +ONLY+ environment variab bundle exec rake generate_guides ONLY=my_guide </plain> -Although by default guides that have not been modified are not processed, so +ONLY+ is rarely needed in practice. +By default, guides that have not been modified are not processed, so +ONLY+ is rarely needed in practice. To force process of all the guides, pass +ALL=1+. -It is also recommended that you work with +WARNINGS=1+, this detects duplicate IDs and warns about broken internal links. +It is also recommended that you work with +WARNINGS=1+. This detects duplicate IDs and warns about broken internal links. -If you want to generate guides in languages other than English, you can keep them in a separate directory under +source+ (eg. <tt>source/es</tt>) and use the +LANGUAGE+ environment variable. +If you want to generate guides in languages other than English, you can keep them in a separate directory under +source+ (eg. <tt>source/es</tt>) and use the +LANGUAGE+ environment variable: <plain> rake generate_guides LANGUAGE=es @@ -70,7 +70,7 @@ rake generate_guides LANGUAGE=es h3. HTML Validation -Please do validate the generated HTML with +Please validate the generated HTML with: <plain> rake validate_guides @@ -80,4 +80,5 @@ Particularly, titles get an ID generated from their content and this often leads h3. Changelog +* March 31, 2011: grammar tweaks by "Josiah Ivey":http://twitter.com/josiahivey * October 5, 2010: ported from the docrails wiki and revised by "Xavier Noria":credits.html#fxn diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile index 893f65856c..c9dc1c2d7c 100644 --- a/railties/guides/source/security.textile +++ b/railties/guides/source/security.textile @@ -893,12 +893,6 @@ h4. Ajax Injection If you use the "in_place_editor plugin":http://dev.rubyonrails.org/browser/plugins/in_place_editing, or actions that return a string, rather than rendering a view, _(highlight)you have to escape the return value in the action_. Otherwise, if the return value contains a XSS string, the malicious code will be executed upon return to the browser. Escape any input value using the h() method. -h4. RJS Injection - --- _Don't forget to escape in JavaScript (RJS) templates, too._ - -The RJS API generates blocks of JavaScript code based on Ruby code, thus allowing you to manipulate a view or parts of a view from the server side. <em class="highlight">If you allow user input in RJS templates, do escape it using +escape_javascript()+ within JavaScript functions, and in HTML parts using +h()+</em>. Otherwise an attacker could execute arbitrary JavaScript. - h4. Command Line Injection -- _Use user-supplied command line parameters with caution._ diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile index d3f72509c6..e2317661ea 100644 --- a/railties/guides/source/testing.textile +++ b/railties/guides/source/testing.textile @@ -79,9 +79,9 @@ steve: Each fixture is given a name followed by an indented list of colon-separated key/value pairs. Records are separated by a blank space. You can place comments in a fixture file by using the # character in the first column. -h5. ERb'in It Up +h5. ERB'in It Up -ERb allows you to embed ruby code within templates. Both the YAML and CSV fixture formats are pre-processed with ERb when you load fixtures. This allows you to use Ruby to help you generate some sample data. +ERB allows you to embed ruby code within templates. Both the YAML and CSV fixture formats are pre-processed with ERB when you load fixtures. This allows you to use Ruby to help you generate some sample data. <erb> <% earth_size = 20 %> @@ -391,7 +391,7 @@ There are a bunch of different types of assertions you can use. Here's the compl |+assert_nil( obj, [msg] )+ |Ensures that +obj.nil?+ is true.| |+assert_not_nil( obj, [msg] )+ |Ensures that +obj.nil?+ is false.| |+assert_match( regexp, string, [msg] )+ |Ensures that a string matches the regular expression.| -|+assert_no_match( regexp, string, [msg] )+ |Ensures that a string doesn't matches the regular expression.| +|+assert_no_match( regexp, string, [msg] )+ |Ensures that a string doesn't match the regular expression.| |+assert_in_delta( expecting, actual, delta, [msg] )+ |Ensures that the numbers +expecting+ and +actual+ are within +delta+ of each other.| |+assert_throws( symbol, [msg] ) { block }+ |Ensures that the given block throws the symbol.| |+assert_raise( exception1, exception2, ... ) { block }+ |Ensures that the given block raises one of the given exceptions.| @@ -592,7 +592,6 @@ There are more assertions that are primarily used in testing views: |_.Assertion |_.Purpose| |+assert_select_email+ |Allows you to make assertions on the body of an e-mail. | -|+assert_select_rjs+ |Allows you to make assertions on an RJS response. +assert_select_rjs+ has variants which allow you to narrow down on the updated element or even a particular operation on an element.| |+assert_select_encoded+ |Allows you to make assertions on encoded HTML. It does this by un-encoding the contents of each element and then calling the block with all the un-encoded elements.| |+css_select(selector)+ or +css_select(element, selector)+ |Returns an array of all the elements selected by the _selector_. In the second variant it first matches the base _element_ and tries to match the _selector_ expression on any of its children. If there are no matches both variants return an empty array.| @@ -748,7 +747,8 @@ You don't need to set up and run your tests by hand on a test-by-test basis. Rai h3. Brief Note About +Test::Unit+ -Ruby ships with a boat load of libraries. One little gem of a library is +Test::Unit+, a framework for unit testing in Ruby. All the basic assertions discussed above are actually defined in +Test::Unit::Assertions+. The class +ActiveSupport::TestCase+ which we have been using in our unit and functional tests extends +Test::Unit::TestCase+ that it is how we can use all the basic assertions in our tests. +Ruby ships with a boat load of libraries. One little gem of a library is +Test::Unit+, a framework for unit testing in Ruby. All the basic assertions discussed above are actually defined in +Test::Unit::Assertions+. The class +ActiveSupport::TestCase+ which we have been using in our unit and functional tests extends +Test::Unit::TestCase+, allowing +us to use all of the basic assertions in our tests. NOTE: For more information on +Test::Unit+, refer to "test/unit Documentation":http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/ diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 1b834275a7..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 @@ -139,9 +137,7 @@ module Rails protected - def default_asset_path - nil - end + alias :build_middleware_stack :app def default_middleware_stack ActionDispatch::MiddlewareStack.new.tap do |middleware| @@ -156,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 @@ -205,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 23b0e765ae..e5476fbe7a 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -4,12 +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 + 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 @@ -29,6 +29,12 @@ module Rails @log_level = nil @middleware = app_middleware @generators = app_generators + + @assets = ActiveSupport::OrderedOptions.new + @assets.enabled = false + @assets.paths = [] + @assets.precompile = [] + @assets.prefix = "/assets" end def compiled_asset_path @@ -56,6 +62,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 a45b61c99c..bf865ce466 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -53,6 +53,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/commands.rb b/railties/lib/rails/commands.rb index 02ccdf8060..4182757346 100644 --- a/railties/lib/rails/commands.rb +++ b/railties/lib/rails/commands.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/inclusion' + ARGV << '--help' if ARGV.empty? aliases = { @@ -69,7 +71,7 @@ when '--version', '-v' require 'rails/commands/application' else - puts "Error: Command not recognized" unless %w(-h --help).include?(command) + puts "Error: Command not recognized" unless command.in?(['-h', '--help']) puts <<-EOT Usage: rails COMMAND [ARGS] diff --git a/railties/lib/rails/commands/application.rb b/railties/lib/rails/commands/application.rb index 3b57b925ba..f3fa1fd54d 100644 --- a/railties/lib/rails/commands/application.rb +++ b/railties/lib/rails/commands/application.rb @@ -1,5 +1,6 @@ require 'rails/version' -if %w(--version -v).include? ARGV.first + +if ['--version', '-v'].include?(ARGV.first) puts "Rails #{Rails::VERSION::STRING}" exit(0) end diff --git a/railties/lib/rails/commands/benchmarker.rb b/railties/lib/rails/commands/benchmarker.rb index 0432261802..f230f405c0 100644 --- a/railties/lib/rails/commands/benchmarker.rb +++ b/railties/lib/rails/commands/benchmarker.rb @@ -1,4 +1,6 @@ -if [nil, "-h", "--help"].include?(ARGV.first) +require 'active_support/core_ext/object/inclusion' + +if ARGV.first.in?([nil, "-h", "--help"]) puts "Usage: rails benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ..." exit 1 end diff --git a/railties/lib/rails/commands/destroy.rb b/railties/lib/rails/commands/destroy.rb index db59cd8ad9..2a84e2a6df 100644 --- a/railties/lib/rails/commands/destroy.rb +++ b/railties/lib/rails/commands/destroy.rb @@ -1,7 +1,9 @@ require 'rails/generators' +require 'active_support/core_ext/object/inclusion' + Rails::Generators.configure! -if [nil, "-h", "--help"].include?(ARGV.first) +if ARGV.first.in?([nil, "-h", "--help"]) Rails::Generators.help 'destroy' exit end diff --git a/railties/lib/rails/commands/generate.rb b/railties/lib/rails/commands/generate.rb index 1b3eef504a..28c1c56352 100644 --- a/railties/lib/rails/commands/generate.rb +++ b/railties/lib/rails/commands/generate.rb @@ -1,7 +1,9 @@ require 'rails/generators' +require 'active_support/core_ext/object/inclusion' + Rails::Generators.configure! -if [nil, "-h", "--help"].include?(ARGV.first) +if ARGV.first.in?([nil, "-h", "--help"]) Rails::Generators.help 'generate' exit end diff --git a/railties/lib/rails/commands/profiler.rb b/railties/lib/rails/commands/profiler.rb index 6d9717b5cd..7959d8a981 100644 --- a/railties/lib/rails/commands/profiler.rb +++ b/railties/lib/rails/commands/profiler.rb @@ -1,4 +1,6 @@ -if [nil, "-h", "--help"].include?(ARGV.first) +require 'active_support/core_ext/object/inclusion' + +if ARGV.first.in?([nil, "-h", "--help"]) $stderr.puts "Usage: rails profiler 'Person.expensive_method(10)' [times] [flat|graph|graph_html]" exit(1) end diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index ee265366ff..87385814f7 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: @@ -427,8 +401,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 +482,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 +506,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 29e693dfb0..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,14 +46,18 @@ module Rails DEFAULT_OPTIONS = { :rails => { + :assets => true, :force_plural => false, :helper => 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 a2eaf7a6fb..481fa95068 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -10,7 +10,7 @@ module Rails module Generators class AppBase < Base DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db ) - JAVASCRIPTS = %w( prototype jquery ) + JAVASCRIPTS = %w( jquery prototype ) attr_accessor :rails_template add_shebang_option! @@ -36,11 +36,11 @@ module Rails class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3", :desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})" - class_option :javascript, :type => :string, :aliases => "-j", :default => "prototype", - :desc => "Preconfigure for selected javascript library (options: #{JAVASCRIPTS.join('/')})" + class_option :javascript, :type => :string, :aliases => "-j", :default => "jquery", + :desc => "Preconfigure for selected JavaScript library (options: #{JAVASCRIPTS.join('/')})" class_option :skip_javascript, :type => :boolean, :aliases => "-J", :default => false, - :desc => "Skip javascript files" + :desc => "Skip JavaScript files" class_option :dev, :type => :boolean, :default => false, :desc => "Setup the #{name} with Gemfile pointing to your Rails checkout" @@ -53,6 +53,9 @@ module Rails class_option :help, :type => :boolean, :aliases => "-h", :group => :rails, :desc => "Show this help message and quit" + + class_option :old_style_hash, :type => :boolean, :default => false, + :desc => "Force using old style hash (:foo => 'bar') on Ruby >= 1.9" end def initialize(*args) @@ -121,30 +124,33 @@ module Rails entry += "\n# gem 'mysql2', :git => 'git://github.com/brianmario/mysql2.git'" end end - entry + entry + "\n" end def rails_gemfile_entry if options.dev? <<-GEMFILE.strip_heredoc - gem 'rails', :path => '#{Rails::Generators::RAILS_DEV_PATH}' - gem 'arel', :git => 'git://github.com/rails/arel.git' - gem 'rack', :git => 'git://github.com/rack/rack.git' + gem 'rails', :path => '#{Rails::Generators::RAILS_DEV_PATH}' + gem 'arel', :git => 'git://github.com/rails/arel.git' + gem 'rack', :git => 'git://github.com/rack/rack.git' + gem 'sprockets', :git => "git://github.com/sstephenson/sprockets.git" GEMFILE elsif options.edge? <<-GEMFILE.strip_heredoc - gem 'rails', :git => 'git://github.com/rails/rails.git' - gem 'arel', :git => 'git://github.com/rails/arel.git' - gem 'rack', :git => 'git://github.com/rack/rack.git' + gem 'rails', :git => 'git://github.com/rails/rails.git' + gem 'arel', :git => 'git://github.com/rails/arel.git' + gem 'rack', :git => 'git://github.com/rack/rack.git' + gem 'sprockets', :git => "git://github.com/sstephenson/sprockets.git" GEMFILE else <<-GEMFILE.strip_heredoc gem 'rails', '#{Rails::VERSION::STRING}' # Bundle edge Rails instead: - # gem 'rails', :git => 'git://github.com/rails/rails.git' - # gem 'arel', :git => 'git://github.com/rails/arel.git' - # gem 'rack', :git => 'git://github.com/rack/rack.git' + # gem 'rails', :git => 'git://github.com/rails/rails.git' + # gem 'arel', :git => 'git://github.com/rails/arel.git' + # gem 'rack', :git => 'git://github.com/rack/rack.git' + # gem 'sprockets', :git => "git://github.com/sstephenson/sprockets.git" GEMFILE end end @@ -159,6 +165,25 @@ module Rails else options[:database] end end + + def gem_for_ruby_debugger + if RUBY_VERSION < "1.9.2" + "gem 'ruby-debug'" + else + "gem 'ruby-debug19', :require => 'ruby-debug'" + end + end + + def gem_for_turn + unless RUBY_VERSION < "1.9.2" + <<-GEMFILE.strip_heredoc + group :test do + # Pretty printed test output + gem 'turn', :require => false + end + GEMFILE + end + end def bundle_if_dev_or_edge bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle') @@ -171,9 +196,22 @@ module Rails def empty_directory_with_gitkeep(destination, config = {}) empty_directory(destination, config) + git_keep(destination) + end + + def git_keep(destination) create_file("#{destination}/.gitkeep") unless options[:skip_git] end + # Returns Ruby 1.9 style key-value pair if current code is running on + # Ruby 1.9.x. Returns the old-style (with hash rocket) otherwise. + def key_value(key, value) + if options[:old_style_hash] || RUBY_VERSION < '1.9' + ":#{key} => #{value}" + else + "#{key}: #{value}" + end + end end end -end +end
\ No newline at end of file diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb index dfecd2a6e4..8d03cb911b 100644 --- a/railties/lib/rails/generators/base.rb +++ b/railties/lib/rails/generators/base.rb @@ -8,6 +8,7 @@ rescue LoadError end require 'rails/generators/actions' +require 'active_support/core_ext/object/inclusion' module Rails module Generators @@ -164,7 +165,7 @@ module Rails names.each do |name| defaults = if options[:type] == :boolean { } - elsif [true, false].include?(default_value_for_option(name, options)) + elsif default_value_for_option(name, options).in?([true, false]) { :banner => "" } else { :desc => "#{name.to_s.humanize} to be invoked", :banner => "NAME" } diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb index 4c46db4d67..a7393cfe18 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb @@ -17,7 +17,7 @@ <% end -%> <td><%%= link_to 'Show', <%= singular_table_name %> %></td> <td><%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>) %></td> - <td><%%= link_to 'Destroy', <%= singular_table_name %>, :confirm => 'Are you sure?', :method => :delete %></td> + <td><%%= link_to 'Destroy', <%= singular_table_name %>, <%= key_value :confirm, "'Are you sure?'" %>, <%= key_value :method, ":delete" %> %></td> </tr> <%% end %> </table> diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb index 64273e4ca4..b26161f1d0 100644 --- a/railties/lib/rails/generators/generated_attribute.rb +++ b/railties/lib/rails/generators/generated_attribute.rb @@ -1,4 +1,5 @@ require 'active_support/time' +require 'active_support/core_ext/object/inclusion' module Rails module Generators @@ -44,7 +45,7 @@ module Rails end def reference? - [ :references, :belongs_to ].include?(self.type) + self.type.in?([:references, :belongs_to]) end end end diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index 2af7f85463..36bc9e055c 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -8,6 +8,9 @@ module Rails class_option :skip_namespace, :type => :boolean, :default => false, :desc => "Skip namespace (affects only isolated applications)" + class_option :old_style_hash, :type => :boolean, :default => false, + :desc => "Force using old style hash (:foo => 'bar') on Ruby >= 1.9" + def initialize(args, *options) #:nodoc: # Unfreeze name in case it's given as a frozen string args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen? @@ -181,6 +184,16 @@ module Rails class_collisions "#{options[:prefix]}#{name}#{options[:suffix]}" end end + + # Returns Ruby 1.9 style key-value pair if current code is running on + # Ruby 1.9.x. Returns the old-style (with hash rocket) otherwise. + def key_value(key, value) + if options[:old_style_hash] || RUBY_VERSION < '1.9' + ":#{key} => #{value}" + else + "#{key}: #{value}" + end + end end 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 3f6ff35a86..4df68d67c7 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -46,6 +46,8 @@ module Rails def app directory 'app' + git_keep 'app/mailers' + git_keep 'app/models' end def config @@ -80,14 +82,7 @@ module Rails end def log - empty_directory "log" - - inside "log" do - %w( server production development test ).each do |file| - create_file "#{file}.log" - chmod "#{file}.log", 0666, :verbose => false - end - end + empty_directory_with_gitkeep "log" end def public_directory @@ -98,27 +93,6 @@ module Rails directory "public/images" end - def stylesheets - empty_directory_with_gitkeep "public/stylesheets" - end - - def javascripts - empty_directory "public/javascripts" - - unless options[:skip_javascript] - copy_file "public/javascripts/#{options[:javascript]}.js" - copy_file "public/javascripts/#{options[:javascript]}_ujs.js", "public/javascripts/rails.js" - - if options[:javascript] == "prototype" - copy_file "public/javascripts/controls.js" - copy_file "public/javascripts/dragdrop.js" - copy_file "public/javascripts/effects.js" - end - end - - copy_file "public/javascripts/application.js" - end - def script directory "script" do |content| "#{shebang}\n" + content @@ -127,19 +101,44 @@ module Rails end def test - directory "test" + empty_directory_with_gitkeep "test/fixtures" + empty_directory_with_gitkeep "test/functional" + empty_directory_with_gitkeep "test/integration" + empty_directory_with_gitkeep "test/unit" + + template "test/performance/browsing_test.rb" + template "test/test_helper.rb" end def tmp - empty_directory "tmp" + empty_directory_with_gitkeep "tmp/cache" + end + + def vendor + vendor_javascripts + vendor_stylesheets + vendor_plugins + end - inside "tmp" do - %w(sessions sockets cache pids).each do |dir| - empty_directory(dir) + def vendor_javascripts + if options[:skip_javascript] + empty_directory_with_gitkeep "vendor/assets/javascripts" + else + copy_file "vendor/assets/javascripts/#{options[:javascript]}.js" + copy_file "vendor/assets/javascripts/#{options[:javascript]}_ujs.js" + + if options[:javascript] == "prototype" + copy_file "vendor/assets/javascripts/controls.js" + copy_file "vendor/assets/javascripts/dragdrop.js" + copy_file "vendor/assets/javascripts/effects.js" end end end + def vendor_stylesheets + empty_directory_with_gitkeep "vendor/assets/stylesheets" + end + def vendor_plugins empty_directory_with_gitkeep "vendor/plugins" end @@ -150,15 +149,14 @@ module Rails # can change in Ruby 1.8.7 when we FileUtils.cd. RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__)) - RESERVED_NAMES = %w[application destroy benchmarker profiler - plugin runner test] + RESERVED_NAMES = %w[application destroy benchmarker profiler plugin runner test] class AppGenerator < AppBase add_shared_options_for "application" # Add bin/rails options - class_option :version, :type => :boolean, :aliases => "-v", :group => :rails, - :desc => "Show Rails version number and quit" + class_option :version, :type => :boolean, :aliases => "-v", :group => :rails, + :desc => "Show Rails version number and quit" def initialize(*args) raise Error, "Options should be given after the application name. For details run: rails --help" if args[0].blank? @@ -168,7 +166,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 @@ -225,14 +223,6 @@ module Rails build(:images) end - def create_public_stylesheets_files - build(:stylesheets) - end - - def create_javascript_files - build(:javascripts) - end - def create_script_files build(:script) end @@ -246,7 +236,7 @@ module Rails end def create_vendor_files - build(:vendor_plugins) + build(:vendor) end def finish_template diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index c383d4842f..0cee7deb72 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -4,28 +4,18 @@ source 'http://rubygems.org' <%= database_gemfile_entry -%> +# Asset template engines +<%= "gem 'json'\n" if RUBY_VERSION < "1.9.2" -%> +gem 'sass', '~> 3.1.0.alpha' +gem 'coffee-script' + # Use unicorn as the web server # gem 'unicorn' # Deploy with Capistrano # gem 'capistrano' -# To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+) -# gem 'ruby-debug' -# gem 'ruby-debug19', :require => 'ruby-debug' - -# Bundle the extra gems: -# gem 'bj' -# gem 'nokogiri' -# gem 'sqlite3' -# gem 'rack-bug', :require => 'rack/bug' - -# Bundle gems for the local environment. Make sure to -# put test-only gems in this group so their generators -# and rake tasks are available in development mode: -# group :development, :test do -# gem 'webrat' -# end +# To use debugger +# <%= gem_for_ruby_debugger %> -# Needed for guides generation -# gem "RedCloth", "~> 4.2" +<%= gem_for_turn -%>
\ No newline at end of file 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 new file mode 100644 index 0000000000..fb5e91caf4 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt @@ -0,0 +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 +<% if options[:javascript] == "prototype" %> +//= require controls +//= require dragdrop +//= require effects +<% end -%> +//= require_tree . diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css new file mode 100644 index 0000000000..ccfff11a5d --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css @@ -0,0 +1,4 @@ +/* + * FIXME: Introduce SCSS & Sprockets + *= require_tree . +*/
\ No newline at end of file diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt index 6d56c331c1..c63d1b6ac5 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt @@ -2,8 +2,8 @@ <html> <head> <title><%= camelized %></title> - <%%= stylesheet_link_tag :all %> - <%%= javascript_include_tag :defaults %> + <%%= stylesheet_link_tag "application" %> + <%%= javascript_include_tag "application" %> <%%= csrf_meta_tags %> </head> <body> diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb index b7f64af339..ff8e6e5f3e 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/application.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb @@ -42,10 +42,10 @@ module <%= app_const_base %> # JavaScript files you want as :defaults (application.js is always included). <% if options[:skip_javascript] -%> config.action_view.javascript_expansions[:defaults] = %w() -<% elsif options[:javascript] == 'jquery' -%> - config.action_view.javascript_expansions[:defaults] = %w(jquery rails) +<% elsif options[:javascript] == 'prototype' -%> + config.action_view.javascript_expansions[:defaults] = %w(prototype effects dragdrop controls rails) <% else -%> - # config.action_view.javascript_expansions[:defaults] = %w(jquery rails) + # config.action_view.javascript_expansions[:defaults] = %w(prototype effects dragdrop controls rails) <% end -%> <% if options[:skip_test_unit] -%> @@ -62,5 +62,8 @@ module <%= app_const_base %> # Enable IdentityMap for Active Record, to disable set to false or remove the line below. config.active_record.identity_map = true <% end -%> + + # Enable the asset pipeline + config.assets.enabled = true end end diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt index bdb897ad33..41b2374eda 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt @@ -11,7 +11,6 @@ # Show full error reports and disable caching config.consider_all_requests_local = true - config.action_view.debug_rjs = true config.action_controller.perform_caching = false # Don't care if the mailer can't send diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt index 62aa06dc3e..ddfe4ba1e1 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt @@ -1,6 +1,6 @@ # Be sure to restart your server when you modify this file. -<%= app_const %>.config.session_store :cookie_store, :key => '_<%= app_name %>_session' +<%= app_const %>.config.session_store :cookie_store, <%= key_value :key, "'_#{app_name}_session'" %> # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information diff --git a/railties/lib/rails/generators/rails/app/templates/db/seeds.rb b/railties/lib/rails/generators/rails/app/templates/db/seeds.rb index 664d8c74c8..9a2efa68a7 100644 --- a/railties/lib/rails/generators/rails/app/templates/db/seeds.rb +++ b/railties/lib/rails/generators/rails/app/templates/db/seeds.rb @@ -3,5 +3,5 @@ # # Examples: # -# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) -# Mayor.create(:name => 'Daley', :city => cities.first) +# cities = City.create([{ <%= key_value :name, "'Chicago'" %> }, { <%= key_value :name, "'Copenhagen'" %> }]) +# Mayor.create(<%= key_value :name, "'Daley'" %>, <%= key_value :city, "cities.first" %>) diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/application.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/application.js deleted file mode 100644 index fe4577696b..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/application.js +++ /dev/null @@ -1,2 +0,0 @@ -// Place your application-specific JavaScript functions and classes here -// This file is automatically included by javascript_include_tag :defaults 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/app/templates/public/javascripts/controls.js b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/controls.js index 7392fb664c..7392fb664c 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/controls.js +++ b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/controls.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/dragdrop.js index 15c6dbca68..15c6dbca68 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js +++ b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/dragdrop.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/effects.js b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/effects.js index c81e6c7d5f..c81e6c7d5f 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/effects.js +++ b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/effects.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery.js b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/jquery.js index aa3a4f34fd..aa3a4f34fd 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery.js +++ b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/jquery.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery_ujs.js b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/jquery_ujs.js index 4dcb3779a2..4dcb3779a2 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery_ujs.js +++ b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/jquery_ujs.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/prototype.js index 474b2231bb..474b2231bb 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js +++ b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/prototype.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype_ujs.js b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/prototype_ujs.js index 2cd1220786..2cd1220786 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype_ujs.js +++ b/railties/lib/rails/generators/rails/app/templates/vendor/assets/javascripts/prototype_ujs.js diff --git a/railties/lib/rails/generators/rails/assets/USAGE b/railties/lib/rails/generators/rails/assets/USAGE new file mode 100644 index 0000000000..adebfd7e6f --- /dev/null +++ b/railties/lib/rails/generators/rails/assets/USAGE @@ -0,0 +1,20 @@ +Description: + Stubs out a new asset placeholders. Pass the asset name, either CamelCased + or under_scored. + + To create assets within a folder, specify the assets name as a + path like 'parent/name'. + + This generates a JavaScript stub in app/assets/javascripts and a stylesheet + stub in app/assets/stylesheets. + + If CoffeeScript is available, JavaScripts will be generated with the .coffee extension. + If Sass 3 is available, stylesheets will be generated with the .scss extension. + +Example: + `rails generate assets posts` + + Posts assets. + Javascript: app/assets/javascripts/posts.js + Stylesheet: app/assets/stylesheets/posts.css + diff --git a/railties/lib/rails/generators/rails/assets/assets_generator.rb b/railties/lib/rails/generators/rails/assets/assets_generator.rb new file mode 100644 index 0000000000..80beb7abfe --- /dev/null +++ b/railties/lib/rails/generators/rails/assets/assets_generator.rb @@ -0,0 +1,39 @@ +module Rails + module Generators + class AssetsGenerator < NamedBase + 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', 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', class_path, "#{asset_name}.#{stylesheet_extension}") + end + + protected + + def asset_name + file_name + end + + def javascript_extension + options.javascript_engine.present? ? + "js.#{options.javascript_engine}" : "js" + end + + def stylesheet_extension + options.stylesheet_engine.present? ? + "css.#{options.stylesheet_engine}" : "css" + end + end + end +end diff --git a/railties/lib/rails/generators/rails/assets/templates/javascript.js b/railties/lib/rails/generators/rails/assets/templates/javascript.js new file mode 100644 index 0000000000..dee720facd --- /dev/null +++ b/railties/lib/rails/generators/rails/assets/templates/javascript.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee b/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee new file mode 100644 index 0000000000..09b2da094a --- /dev/null +++ b/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee @@ -0,0 +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/ diff --git a/railties/lib/rails/generators/rails/assets/templates/stylesheet.css b/railties/lib/rails/generators/rails/assets/templates/stylesheet.css new file mode 100644 index 0000000000..7594abf268 --- /dev/null +++ b/railties/lib/rails/generators/rails/assets/templates/stylesheet.css @@ -0,0 +1,4 @@ +/* + Place all the styles related to the matching controller here. + They will automatically be included in application.css. +*/ diff --git a/railties/lib/rails/generators/rails/assets/templates/stylesheet.css.scss b/railties/lib/rails/generators/rails/assets/templates/stylesheet.css.scss new file mode 100644 index 0000000000..ba95e217cc --- /dev/null +++ b/railties/lib/rails/generators/rails/assets/templates/stylesheet.css.scss @@ -0,0 +1,5 @@ +/* + Place all the styles related to the matching controller here. + They will automatically be included in application.css. + You can use Sass (SCSS) here: http://sass-lang.com/ +*/ diff --git a/railties/lib/rails/generators/rails/controller/controller_generator.rb b/railties/lib/rails/generators/rails/controller/controller_generator.rb index 9788c0d0bc..74aa0432a8 100644 --- a/railties/lib/rails/generators/rails/controller/controller_generator.rb +++ b/railties/lib/rails/generators/rails/controller/controller_generator.rb @@ -14,7 +14,7 @@ module Rails end end - hook_for :template_engine, :test_framework, :helper + hook_for :template_engine, :test_framework, :helper, :assets end end end 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..81563f81d3 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,15 @@ 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" + 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" end end @@ -61,8 +66,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, @@ -94,26 +103,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] + return if options.skip_javascript? - empty_directory "#{app_templates_dir}/public/javascripts" - - 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 +149,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? @@ -200,6 +219,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/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/scaffold/templates/scaffold.css.scss b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss new file mode 100644 index 0000000000..45116b53f6 --- /dev/null +++ b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss @@ -0,0 +1,58 @@ +body { background-color: #fff; color: #333; } + +body, p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; +} + +a { + color: #000; + &:visited { color: #666; } + &:hover { color: #fff; background-color:#000; } +} + +div.field, div.actions { + margin-bottom: 10px; +} + +#notice { + color: green; +} + +.field_with_errors { + padding: 2px; + background-color: red; + display: table; +} + +#error_explanation { + width: 450px; + border: 2px solid red; + padding: 7px; + padding-bottom: 0; + margin-bottom: 20px; + background-color: #f0f0f0; + + h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + margin-bottom: 0px; + background-color: #c00; + color: #fff; + } + + ul li { + font-size: 12px; + list-style: square; + } +}
\ No newline at end of file diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb index b5317a055b..32b961d9fc 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb @@ -1,35 +1,35 @@ <% module_namespacing do -%> class <%= controller_class_name %>Controller < ApplicationController # GET <%= route_url %> - # GET <%= route_url %>.xml + # GET <%= route_url %>.json def index @<%= plural_table_name %> = <%= orm_class.all(class_name) %> respond_to do |format| format.html # index.html.erb - format.xml { render :xml => @<%= plural_table_name %> } + format.json { render <%= key_value :json, "@#{plural_table_name}" %> } end end # GET <%= route_url %>/1 - # GET <%= route_url %>/1.xml + # GET <%= route_url %>/1.json def show @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> respond_to do |format| format.html # show.html.erb - format.xml { render :xml => @<%= singular_table_name %> } + format.json { render <%= key_value :json, "@#{singular_table_name}" %> } end end # GET <%= route_url %>/new - # GET <%= route_url %>/new.xml + # GET <%= route_url %>/new.json def new @<%= singular_table_name %> = <%= orm_class.build(class_name) %> respond_to do |format| format.html # new.html.erb - format.xml { render :xml => @<%= singular_table_name %> } + format.json { render <%= key_value :json, "@#{singular_table_name}" %> } end end @@ -39,46 +39,46 @@ class <%= controller_class_name %>Controller < ApplicationController end # POST <%= route_url %> - # POST <%= route_url %>.xml + # POST <%= route_url %>.json def create @<%= singular_table_name %> = <%= orm_class.build(class_name, "params[:#{singular_table_name}]") %> respond_to do |format| if @<%= orm_instance.save %> - format.html { redirect_to(@<%= singular_table_name %>, :notice => '<%= human_name %> was successfully created.') } - format.xml { render :xml => @<%= singular_table_name %>, :status => :created, :location => @<%= singular_table_name %> } + format.html { redirect_to @<%= singular_table_name %>, <%= key_value :notice, "'#{human_name} was successfully created.'" %> } + format.json { render <%= key_value :json, "@#{singular_table_name}" %>, <%= key_value :status, ':created' %>, <%= key_value :location, "@#{singular_table_name}" %> } else - format.html { render :action => "new" } - format.xml { render :xml => @<%= orm_instance.errors %>, :status => :unprocessable_entity } + format.html { render <%= key_value :action, '"new"' %> } + format.json { render <%= key_value :json, "@#{orm_instance.errors}" %>, <%= key_value :status, ':unprocessable_entity' %> } end end end # PUT <%= route_url %>/1 - # PUT <%= route_url %>/1.xml + # PUT <%= route_url %>/1.json def update @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> respond_to do |format| if @<%= orm_instance.update_attributes("params[:#{singular_table_name}]") %> - format.html { redirect_to(@<%= singular_table_name %>, :notice => '<%= human_name %> was successfully updated.') } - format.xml { head :ok } + format.html { redirect_to @<%= singular_table_name %>, <%= key_value :notice, "'#{human_name} was successfully updated.'" %> } + format.json { head :ok } else - format.html { render :action => "edit" } - format.xml { render :xml => @<%= orm_instance.errors %>, :status => :unprocessable_entity } + format.html { render <%= key_value :action, '"edit"' %> } + format.json { render <%= key_value :json, "@#{orm_instance.errors}" %>, <%= key_value :status, ':unprocessable_entity' %> } end end end # DELETE <%= route_url %>/1 - # DELETE <%= route_url %>/1.xml + # DELETE <%= route_url %>/1.json def destroy @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> @<%= orm_instance.destroy %> respond_to do |format| - format.html { redirect_to(<%= index_helper %>_url) } - format.xml { head :ok } + format.html { redirect_to <%= index_helper %>_url } + format.json { head :ok } end end end 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 ce68443c39..0000000000 --- a/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Rails - module Generators - class StylesheetsGenerator < Base - def copy_stylesheets_file - template "scaffold.css", "public/stylesheets/scaffold.css" if behavior == :invoke - end - end - end -end diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb index 964d59d84c..01fe6dda7a 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb @@ -19,30 +19,30 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase test "should create <%= singular_table_name %>" do assert_difference('<%= class_name %>.count') do - post :create, :<%= singular_table_name %> => @<%= singular_table_name %>.attributes + post :create, <%= key_value singular_table_name, "@#{singular_table_name}.attributes" %> end assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>)) end test "should show <%= singular_table_name %>" do - get :show, :id => @<%= singular_table_name %>.to_param + get :show, <%= key_value :id, "@#{singular_table_name}.to_param" %> assert_response :success end test "should get edit" do - get :edit, :id => @<%= singular_table_name %>.to_param + get :edit, <%= key_value :id, "@#{singular_table_name}.to_param" %> assert_response :success end test "should update <%= singular_table_name %>" do - put :update, :id => @<%= singular_table_name %>.to_param, :<%= singular_table_name %> => @<%= singular_table_name %>.attributes + put :update, <%= key_value :id, "@#{singular_table_name}.to_param" %>, <%= key_value singular_table_name, "@#{singular_table_name}.attributes" %> assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>)) end test "should destroy <%= singular_table_name %>" do assert_difference('<%= class_name %>.count', -1) do - delete :destroy, :id => @<%= singular_table_name %>.to_param + delete :destroy, <%= key_value :id, "@#{singular_table_name}.to_param" %> end assert_redirected_to <%= index_helper %>_path 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/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb index 591fd6f6bd..6d6e7f8b59 100644 --- a/railties/lib/rails/source_annotation_extractor.rb +++ b/railties/lib/rails/source_annotation_extractor.rb @@ -11,7 +11,7 @@ # # Annotations are looked for in comments and modulus whitespace they have to # start with the tag optionally followed by a colon. Everything up to the end -# of the line (or closing ERb comment tag) is considered to be their text. +# of the line (or closing ERB comment tag) is considered to be their text. class SourceAnnotationExtractor class Annotation < Struct.new(:line, :tag, :text) @@ -30,7 +30,7 @@ class SourceAnnotationExtractor # Prints all annotations with tag +tag+ under the root directories +app+, +lib+, # and +test+ (recursively). Only filenames with extension +.builder+, +.rb+, - # +.rxml+, +.rjs+, +.rhtml+, or +.erb+ are taken into account. The +options+ + # +.rxml+, +.rhtml+, or +.erb+ are taken into account. The +options+ # hash is passed to each annotation's +to_s+. # # This class method is the single entry point for the rake tasks. @@ -47,7 +47,7 @@ class SourceAnnotationExtractor # Returns a hash that maps filenames under +dirs+ (recursively) to arrays # with their annotations. Only files with annotations are included, and only - # those with extension +.builder+, +.rb+, +.rxml+, +.rjs+, +.rhtml+, and +.erb+ + # those with extension +.builder+, +.rb+, +.rxml+, +.rhtml+, and +.erb+ # are taken into account. def find(dirs=%w(app lib test)) dirs.inject({}) { |h, dir| h.update(find_in(dir)) } @@ -55,7 +55,7 @@ class SourceAnnotationExtractor # Returns a hash that maps filenames under +dir+ (recursively) to arrays # with their annotations. Only files with annotations are included, and only - # those with extension +.builder+, +.rb+, +.rxml+, +.rjs+, +.rhtml+, and +.erb+ + # those with extension +.builder+, +.rb+, +.rxml+, +.rhtml+, and +.erb+ # are taken into account. def find_in(dir) results = {} @@ -99,4 +99,4 @@ class SourceAnnotationExtractor puts end end -end
\ No newline at end of file +end diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb index af52014728..166d518f7c 100644 --- a/railties/lib/rails/tasks.rb +++ b/railties/lib/rails/tasks.rb @@ -3,6 +3,7 @@ $VERBOSE = nil # Load Rails rakefile extensions %w( annotations + assets documentation framework log @@ -11,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 new file mode 100644 index 0000000000..396ce728a1 --- /dev/null +++ b/railties/lib/rails/tasks/assets.rake @@ -0,0 +1,6 @@ +namespace :assets do + task :compile => :environment do + assets = Rails.application.config.assets.precompile + Rails.application.assets.precompile(*assets) + end +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/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb index b9f7bdc2eb..41485c8bac 100644 --- a/railties/lib/rails/test_help.rb +++ b/railties/lib/rails/test_help.rb @@ -14,10 +14,14 @@ if defined?(Test::Unit::Util::BacktraceFilter) && ENV['BACKTRACE'].nil? end if defined?(MiniTest) - require 'turn' + # Enable turn if it is available + begin + require 'turn' - if MiniTest::Unit.respond_to?(:use_natural_language_case_names=) - MiniTest::Unit.use_natural_language_case_names = true + if MiniTest::Unit.respond_to?(:use_natural_language_case_names=) + MiniTest::Unit.use_natural_language_case_names = true + end + rescue LoadError end end diff --git a/railties/railties.gemspec b/railties/railties.gemspec index b1eda71c7f..cd0646b8ed 100644 --- a/railties/railties.gemspec +++ b/railties/railties.gemspec @@ -21,7 +21,6 @@ Gem::Specification.new do |s| s.add_dependency('rake', '>= 0.8.7') s.add_dependency('thor', '~> 0.14.4') s.add_dependency('rack-ssl', '~> 1.3.2') - s.add_dependency('turn', '~> 0.8.2') s.add_dependency('activesupport', version) s.add_dependency('actionpack', version) end diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 044fd2a278..62697b1bf9 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -1,5 +1,18 @@ require "isolation/abstract_unit" +class ::MyMailInterceptor + def self.delivering_email(email); email; end +end + +class ::MyOtherMailInterceptor < ::MyMailInterceptor; end + +class ::MyMailObserver + def self.delivered_email(email); email; end +end + +class ::MyOtherMailObserver < ::MyMailObserver; end + + module ApplicationTests class ConfigurationTest < Test::Unit::TestCase include ActiveSupport::Testing::Isolation @@ -245,6 +258,80 @@ module ApplicationTests assert_equal res, last_response.body # value should be unchanged end + test "registers interceptors with ActionMailer" do + add_to_config <<-RUBY + config.action_mailer.interceptors = MyMailInterceptor + RUBY + + require "#{app_path}/config/environment" + require "mail" + + ActionMailer::Base + + assert_equal [::MyMailInterceptor], ::Mail.send(:class_variable_get, "@@delivery_interceptors") + end + + test "registers multiple interceptors with ActionMailer" do + add_to_config <<-RUBY + config.action_mailer.interceptors = [MyMailInterceptor, "MyOtherMailInterceptor"] + RUBY + + require "#{app_path}/config/environment" + require "mail" + + ActionMailer::Base + + assert_equal [::MyMailInterceptor, ::MyOtherMailInterceptor], ::Mail.send(:class_variable_get, "@@delivery_interceptors") + end + + test "registers observers with ActionMailer" do + add_to_config <<-RUBY + config.action_mailer.observers = MyMailObserver + RUBY + + require "#{app_path}/config/environment" + require "mail" + + ActionMailer::Base + + assert_equal [::MyMailObserver], ::Mail.send(:class_variable_get, "@@delivery_notification_observers") + end + + test "registers multiple observers with ActionMailer" do + add_to_config <<-RUBY + config.action_mailer.observers = [MyMailObserver, "MyOtherMailObserver"] + RUBY + + require "#{app_path}/config/environment" + require "mail" + + ActionMailer::Base + + assert_equal [::MyMailObserver, ::MyOtherMailObserver], ::Mail.send(:class_variable_get, "@@delivery_notification_observers") + end + + test "valid timezone is setup correctly" do + add_to_config <<-RUBY + config.root = "#{app_path}" + config.time_zone = "Wellington" + RUBY + + require "#{app_path}/config/environment" + + assert_equal "Wellington", Rails.application.config.time_zone + end + + test "raises when an invalid timezone is defined in the config" do + add_to_config <<-RUBY + config.root = "#{app_path}" + config.time_zone = "That big hill over yonder hill" + RUBY + + assert_raise(ArgumentError) do + require "#{app_path}/config/environment" + end + end + test "config.action_controller.perform_caching = false" do make_basic_app do |app| app.config.action_controller.perform_caching = false diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 018c2fa6bf..3ef06c7f25 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 @@ -22,8 +24,6 @@ DEFAULT_APP_FILES = %w( lib/tasks log public/images - public/javascripts - public/stylesheets 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 @@ -146,43 +145,40 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/ end - def test_prototype_and_test_unit_are_added_by_default + 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\(jquery rails\)/ - assert_file "public/javascripts/application.js" - assert_file "public/javascripts/prototype.js" - assert_file "public/javascripts/rails.js" - assert_file "public/javascripts/controls.js" - assert_file "public/javascripts/dragdrop.js" - assert_file "public/javascripts/effects.js" + assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/ + 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/prototype.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\(jquery rails\)/ - assert_file "public/javascripts/application.js" - assert_file "public/javascripts/prototype.js" - assert_file "public/javascripts/controls.js" - assert_file "public/javascripts/dragdrop.js" - assert_file "public/javascripts/effects.js" - assert_file "public/javascripts/rails.js", /prototype/ + assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/ + 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\(jquery rails\)/ - assert_file "public/javascripts/application.js" - assert_file "public/javascripts/jquery.js" - assert_file "public/javascripts/rails.js", /jQuery/ + assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/ + 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 @@ -216,6 +212,24 @@ class AppGeneratorTest < Rails::Generators::TestCase end end + def test_new_hash_style + run_generator [destination_root] + assert_file "config/initializers/session_store.rb" do |file| + if RUBY_VERSION < "1.9" + assert_match /config.session_store :cookie_store, :key => '_.+_session'/, file + else + assert_match /config.session_store :cookie_store, key: '_.+_session'/, file + end + end + end + + def test_force_old_style_hash + run_generator [destination_root, "--old-style-hash"] + assert_file "config/initializers/session_store.rb" do |file| + assert_match /config.session_store :cookie_store, :key => '_.+_session'/, file + end + end + protected def action(*args, &block) diff --git a/railties/test/generators/assets_generator_test.rb b/railties/test/generators/assets_generator_test.rb new file mode 100644 index 0000000000..e99f0f092a --- /dev/null +++ b/railties/test/generators/assets_generator_test.rb @@ -0,0 +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 +class AssetsGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper + arguments %w(posts) + + def test_assets + run_generator + 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", "--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_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 be99dc068d..655d8ad450 100644 --- a/railties/test/generators/controller_generator_test.rb +++ b/railties/test/generators/controller_generator_test.rb @@ -37,6 +37,12 @@ class ControllerGeneratorTest < Rails::Generators::TestCase assert_no_file "test/unit/helpers/account_helper_test.rb" end + def test_invokes_assets + run_generator + assert_file "app/assets/javascripts/account.js" + assert_file "app/assets/stylesheets/account.css" + end + def test_invokes_default_test_framework run_generator assert_file "test/functional/account_controller_test.rb" diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index 3c11c8dbaf..d20335ad95 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -95,41 +95,33 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase def test_skipping_javascripts_without_mountable_option run_generator - assert_no_file "public/javascripts/prototype.js" - assert_no_file "public/javascripts/rails.js" - assert_no_file "public/javascripts/controls.js" - assert_no_file "public/javascripts/dragdrop.js" - assert_no_file "public/javascripts/dragdrop.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/rails.js" - assert_file "public/javascripts/prototype.js" - assert_file "public/javascripts/controls.js" - assert_file "public/javascripts/dragdrop.js" - assert_file "public/javascripts/dragdrop.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/prototype.js" - assert_no_file "public/javascripts/rails.js" - assert_no_file "public/javascripts/controls.js" - assert_no_file "public/javascripts/dragdrop.js" - assert_no_file "public/javascripts/dragdrop.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", "jquery"] - assert_file "test/dummy/public/javascripts/jquery.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/prototype.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 @@ -153,6 +145,12 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase 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/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"/ @@ -227,3 +225,4 @@ protected silence(:stdout){ generator.send(*args, &block) } end end + diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index d55ed22975..c7f45a807d 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -122,4 +122,22 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase ensure Unknown::Generators.send :remove_const, :ActiveModel end + + def test_new_hash_style + run_generator + assert_file "app/controllers/users_controller.rb" do |content| + if RUBY_VERSION < "1.9" + assert_match /\{ render :action => "new" \}/, content + else + assert_match /\{ render action: "new" \}/, content + end + end + end + + def test_force_old_style_hash + run_generator ["User", "--old-style-hash"] + assert_file "app/controllers/users_controller.rb" do |content| + assert_match /\{ render :action => "new" \}/, content + end + 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 aaeb686daa..0000000000 --- a/railties/test/generators/stylesheets_generator_test.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'generators/generators_test_helper' -require 'rails/generators/rails/stylesheets/stylesheets_generator' - -class StylesheetsGeneratorTest < Rails::Generators::TestCase - include GeneratorsTestHelper - - def test_copy_stylesheets - run_generator - assert_file "public/stylesheets/scaffold.css" - end - - def test_stylesheets_are_not_deleted_on_revoke - run_generator - run_generator [], :behavior => :revoke - assert_file "public/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..7605984684 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,70 +584,6 @@ 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") - - @plugin.write "lib/bukkits.rb", <<-RUBY - module Bukkits - class Engine < ::Rails::Engine - isolate_namespace Bukkits - end - 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 %> - RUBY - - @plugin.write "app/controllers/bukkits/home_controller.rb", <<-RUBY - module Bukkits - class HomeController < ActionController::Base - def index - render :text => "Good morning!", :layout => "bukkits/application" - 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" - end - RUBY - - require 'rack/test' - extend Rack::Test::Methods - - 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 - end - private def app Rails.application diff --git a/railties/test/railties/shared_tests.rb b/railties/test/railties/shared_tests.rb index 3eb79d57c8..b2b18938ae 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.coffee", "square = (x) -> x * x" - @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 "square = function(x) {", last_response.body end def test_copying_migrations |