diff options
-rw-r--r-- | actionpack/CHANGELOG.md | 44 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/mime_negotiation.rb | 21 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 62 | ||||
-rw-r--r-- | actionpack/test/abstract_unit.rb | 29 | ||||
-rw-r--r-- | actionpack/test/controller/resources_test.rb | 29 | ||||
-rw-r--r-- | actionpack/test/dispatch/routing/concerns_test.rb | 82 | ||||
-rw-r--r-- | activemodel/CHANGELOG.md | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | activemodel/lib/active_model/serializers/xml.rb | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | activemodel/test/cases/serializers/xml_serialization_test.rb | 38 | ||||
-rw-r--r-- | activerecord/CHANGELOG.md | 11 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 4 | ||||
-rw-r--r-- | activerecord/test/cases/relations_test.rb | 4 | ||||
-rw-r--r-- | guides/source/4_0_release_notes.textile | 31 | ||||
-rw-r--r-- | guides/source/contributing_to_ruby_on_rails.textile | 60 | ||||
-rw-r--r-- | guides/source/routing.textile | 30 | ||||
-rw-r--r-- | railties/lib/rails/console/app.rb | 3 |
16 files changed, 385 insertions, 69 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 2e683e7c47..516fcbe62f 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,49 @@ ## Rails 4.0.0 (unreleased) ## +* Add Request#formats=(extensions) that lets you set multiple formats directly in a prioritized order *DHH* + + Example of using this for custom iphone views with an HTML fallback: + + class ApplicationController < ActionController::Base + before_filter :adjust_format_for_iphone_with_html_fallback + + private + def adjust_format_for_iphone_with_html_fallback + request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/] + end + end + + +* Add Routing Concerns to declare common routes that can be reused inside + others resources and routes. + + Code before: + + resources :messages do + resources :comments + end + + resources :posts do + resources :comments + resources :images, only: :index + end + + Code after: + + concern :commentable do + resources :comments + end + + concern :image_attachable do + resources :images, only: :index + end + + resources :messages, concerns: :commentable + + resources :posts, concerns: [:commentable, :image_attachable] + + *DHH + Rafael Mendonça França* + * Add start_hour and end_hour options to the select_hour helper. *Evan Tann* * Raises an ArgumentError when the first argument in `form_for` contain `nil` diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb index e31f3b823d..0f98e84788 100644 --- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb +++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb @@ -80,6 +80,27 @@ module ActionDispatch @env["action_dispatch.request.formats"] = [Mime::Type.lookup_by_extension(parameters[:format])] end + # Sets the \formats by string extensions. This differs from #format= by allowing you + # to set multiple, ordered formats, which is useful when you want to have a fallback. + # + # In this example, the :iphone format will be used if it's available, otherwise it'll fallback + # to the :html format. + # + # class ApplicationController < ActionController::Base + # before_filter :adjust_format_for_iphone_with_html_fallback + # + # private + # def adjust_format_for_iphone_with_html_fallback + # request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/] + # end + # end + def formats=(extensions) + parameters[:format] = extensions.first.to_s + @env["action_dispatch.request.formats"] = extensions.collect do |extension| + Mime::Type.lookup_by_extension(extension) + end + end + # Receives an array of mimes and return the first user sent mime that # matches the order array. # diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 5e2f1ff1e0..ea5028a7c0 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -909,7 +909,7 @@ module ActionDispatch # CANONICAL_ACTIONS holds all actions that does not need a prefix or # a path appended since they fit properly in their scope level. VALID_ON_OPTIONS = [:new, :collection, :member] - RESOURCE_OPTIONS = [:as, :controller, :path, :only, :except, :param] + RESOURCE_OPTIONS = [:as, :controller, :path, :only, :except, :param, :concerns] CANONICAL_ACTIONS = %w(index create new show update destroy) class Resource #:nodoc: @@ -1046,6 +1046,8 @@ module ActionDispatch resource_scope(:resource, SingletonResource.new(resources.pop, options)) do yield if block_given? + concerns(options[:concerns]) if options[:concerns] + collection do post :create end if parent_resource.actions.include?(:create) @@ -1210,6 +1212,8 @@ module ActionDispatch resource_scope(:resources, Resource.new(resources.pop, options)) do yield if block_given? + concerns(options[:concerns]) if options[:concerns] + collection do get :index if parent_resource.actions.include?(:index) post :create if parent_resource.actions.include?(:create) @@ -1580,15 +1584,71 @@ module ActionDispatch end end + # Routing Concerns allows you to declare common routes that can be reused + # inside others resources and routes. + # + # concern :commentable do + # resources :comments + # end + # + # concern :image_attachable do + # resources :images, only: :index + # end + # + # These concerns are used in Resources routing: + # + # resources :messages, concerns: [:commentable, :image_attachable] + # + # or in a scope or namespace: + # + # namespace :posts do + # concerns :commentable + # end + module Concerns + # Define a routing concern using a name. + # + # concern :commentable do + # resources :comments + # end + # + # Any routing helpers can be used inside a concern. + def concern(name, &block) + @concerns[name] = block + end + + # Use the named concerns + # + # resources :posts do + # concerns :commentable + # end + # + # concerns also work in any routes helper that you want to use: + # + # namespace :posts do + # concerns :commentable + # end + def concerns(*names) + names.flatten.each do |name| + if concern = @concerns[name] + instance_eval(&concern) + else + raise ArgumentError, "No concern named #{name} was found!" + end + end + end + end + def initialize(set) #:nodoc: @set = set @scope = { :path_names => @set.resources_path_names } + @concerns = {} end include Base include HttpHelpers include Redirection include Scoping + include Concerns include Resources end end diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index b914bbce4d..e5054a9eb8 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -349,3 +349,32 @@ module RoutingTestHelpers set.send(:url_for, options.merge(:only_path => true, :_recall => recall)) end end + +class ResourcesController < ActionController::Base + def index() render :nothing => true end + alias_method :show, :index +end + +class ThreadsController < ResourcesController; end +class MessagesController < ResourcesController; end +class CommentsController < ResourcesController; end +class AuthorsController < ResourcesController; end +class LogosController < ResourcesController; end + +class AccountsController < ResourcesController; end +class AdminController < ResourcesController; end +class ProductsController < ResourcesController; end +class ImagesController < ResourcesController; end +class PreferencesController < ResourcesController; end + +module Backoffice + class ProductsController < ResourcesController; end + class TagsController < ResourcesController; end + class ManufacturersController < ResourcesController; end + class ImagesController < ResourcesController; end + + module Admin + class ProductsController < ResourcesController; end + class ImagesController < ResourcesController; end + end +end diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index 236e16c68e..305659b219 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -2,35 +2,6 @@ require 'abstract_unit' require 'active_support/core_ext/object/try' require 'active_support/core_ext/object/with_options' -class ResourcesController < ActionController::Base - def index() render :nothing => true end - alias_method :show, :index -end - -class ThreadsController < ResourcesController; end -class MessagesController < ResourcesController; end -class CommentsController < ResourcesController; end -class AuthorsController < ResourcesController; end -class LogosController < ResourcesController; end - -class AccountsController < ResourcesController; end -class AdminController < ResourcesController; end -class ProductsController < ResourcesController; end -class ImagesController < ResourcesController; end -class PreferencesController < ResourcesController; end - -module Backoffice - class ProductsController < ResourcesController; end - class TagsController < ResourcesController; end - class ManufacturersController < ResourcesController; end - class ImagesController < ResourcesController; end - - module Admin - class ProductsController < ResourcesController; end - class ImagesController < ResourcesController; end - end -end - class ResourcesTest < ActionController::TestCase def test_default_restful_routes with_restful_routing :messages do diff --git a/actionpack/test/dispatch/routing/concerns_test.rb b/actionpack/test/dispatch/routing/concerns_test.rb new file mode 100644 index 0000000000..21da3bd77a --- /dev/null +++ b/actionpack/test/dispatch/routing/concerns_test.rb @@ -0,0 +1,82 @@ +require 'abstract_unit' + +class RoutingConcernsTest < ActionDispatch::IntegrationTest + Routes = ActionDispatch::Routing::RouteSet.new.tap do |app| + app.draw do + concern :commentable do + resources :comments + end + + concern :image_attachable do + resources :images, only: :index + end + + resources :posts, concerns: [:commentable, :image_attachable] do + resource :video, concerns: :commentable + end + + resource :picture, concerns: :commentable do + resources :posts, concerns: :commentable + end + + scope "/videos" do + concerns :commentable + end + end + end + + include Routes.url_helpers + def app; Routes end + + def test_accessing_concern_from_resources + get "/posts/1/comments" + assert_equal "200", @response.code + assert_equal "/posts/1/comments", post_comments_path(post_id: 1) + end + + def test_accessing_concern_from_resource + get "/picture/comments" + assert_equal "200", @response.code + assert_equal "/picture/comments", picture_comments_path + end + + def test_accessing_concern_from_nested_resource + get "/posts/1/video/comments" + assert_equal "200", @response.code + assert_equal "/posts/1/video/comments", post_video_comments_path(post_id: 1) + end + + def test_accessing_concern_from_nested_resources + get "/picture/posts/1/comments" + assert_equal "200", @response.code + assert_equal "/picture/posts/1/comments", picture_post_comments_path(post_id: 1) + end + + def test_accessing_concern_from_resources_with_more_than_one_concern + get "/posts/1/images" + assert_equal "200", @response.code + assert_equal "/posts/1/images", post_images_path(post_id: 1) + end + + def test_accessing_concern_from_resources_using_only_option + get "/posts/1/image/1" + assert_equal "404", @response.code + end + + def test_accessing_concern_from_a_scope + get "/videos/comments" + assert_equal "200", @response.code + end + + def test_with_an_invalid_concern_name + e = assert_raise ArgumentError do + ActionDispatch::Routing::RouteSet.new.tap do |app| + app.draw do + resources :posts, concerns: :foo + end + end + end + + assert_equal "No concern named foo was found!", e.message + end +end diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 9188719b78..12e0956d3c 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,5 +1,7 @@ ## Rails 4.0.0 (unreleased) ## +* Changed `ActiveModel::Serializers::Xml::Serializer#add_associations` to by default propagate `:skip_types, :dasherize, :camelize` keys to included associations. It can be overriden on each association by explicitly specifying the option on one or more associations *Anthony Alberto* + * Changed `AM::Serializers::JSON.include_root_in_json' default value to false. Now, AM Serializers and AR objects have the same default behaviour. Fixes #6578. diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb index 016d821fdf..cf742d0569 100644..100755 --- a/activemodel/lib/active_model/serializers/xml.rb +++ b/activemodel/lib/active_model/serializers/xml.rb @@ -115,6 +115,10 @@ module ActiveModel merged_options = opts.merge(options.slice(:builder, :indent)) merged_options[:skip_instruct] = true + [:skip_types, :dasherize, :camelize].each do |key| + merged_options[key] = options[key] if merged_options[key].nil? && !options[key].nil? + end + if records.respond_to?(:to_ary) records = records.to_ary diff --git a/activemodel/test/cases/serializers/xml_serialization_test.rb b/activemodel/test/cases/serializers/xml_serialization_test.rb index a93323a3a8..8c5a3c5efd 100644..100755 --- a/activemodel/test/cases/serializers/xml_serialization_test.rb +++ b/activemodel/test/cases/serializers/xml_serialization_test.rb @@ -28,7 +28,7 @@ class Address extend ActiveModel::Naming include ActiveModel::Serializers::Xml - attr_accessor :street, :city, :state, :zip + attr_accessor :street, :city, :state, :zip, :apt_number def attributes instance_values @@ -56,6 +56,7 @@ class XmlSerializationTest < ActiveModel::TestCase @contact.address.city = "Springfield" @contact.address.state = "CA" @contact.address.zip = 11111 + @contact.address.apt_number = 35 @contact.friends = [Contact.new, Contact.new] end @@ -222,4 +223,39 @@ class XmlSerializationTest < ActiveModel::TestCase assert_match %r{<friends>}, xml assert_match %r{<friend>}, xml end + + test "propagates skip-types option to included associations and attributes" do + xml = @contact.to_xml :skip_types => true, :include => :address, :indent => 0 + assert_match %r{<address>}, xml + assert_match %r{<apt-number>}, xml + end + + test "propagates camelize option to included associations and attributes" do + xml = @contact.to_xml :camelize => true, :include => :address, :indent => 0 + assert_match %r{<Address>}, xml + assert_match %r{<AptNumber type="integer">}, xml + end + + test "propagates dasherize option to included associations and attributes" do + xml = @contact.to_xml :dasherize => false, :include => :address, :indent => 0 + assert_match %r{<apt_number type="integer">}, xml + end + + test "don't propagate skip_types if skip_types is defined at the included association level" do + xml = @contact.to_xml :skip_types => true, :include => { :address => { :skip_types => false } }, :indent => 0 + assert_match %r{<address>}, xml + assert_match %r{<apt-number type="integer">}, xml + end + + test "don't propagate camelize if camelize is defined at the included association level" do + xml = @contact.to_xml :camelize => true, :include => { :address => { :camelize => false } }, :indent => 0 + assert_match %r{<address>}, xml + assert_match %r{<apt-number type="integer">}, xml + end + + test "don't propagate dasherize if dasherize is defined at the included association level" do + xml = @contact.to_xml :dasherize => false, :include => { :address => { :dasherize => true } }, :indent => 0 + assert_match %r{<address>}, xml + assert_match %r{<apt-number type="integer">}, xml + end end diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 7a549397a0..faf1bbf232 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,9 @@ ## Rails 4.0.0 (unreleased) ## +* Raise `ArgumentError` if list of attributes to change is empty in `update_all`. + + *Roman Shatsov* + * Fix AR#create to return an unsaved record when AR::RecordInvalid is raised. Fixes #3217. @@ -586,7 +590,6 @@ * PostgreSQL hstore types are automatically deserialized from the database. - ## Rails 3.2.8 (Aug 9, 2012) ## * Do not consider the numeric attribute as changed if the old value is zero and the new value @@ -595,12 +598,6 @@ *Rafael Mendonça França* -* Do not consider the numeric attribute as changed if the old value is zero and the new value - is not a string. - Fixes #7237. - - *Rafael Mendonça França* - * Removes the deprecation of `update_attribute`. *fxn* * Reverted the deprecation of `composed_of`. *Rafael Mendonça França* diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 9ed3256ae9..1abbc58314 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -258,6 +258,8 @@ module ActiveRecord # # Update all books that match conditions, but limit it to 5 ordered by date # Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(:author => 'David') def update_all(updates) + raise ArgumentError, "Empty list of attributes to change" if updates.blank? + stmt = Arel::UpdateManager.new(arel.engine) stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates)) @@ -466,7 +468,7 @@ module ActiveRecord # Returns sql statement for the relation. # # Users.where(name: 'Oscar').to_sql - # # => SELECT "users".* FROM "users" WHERE "users"."name" = 'Oscar' + # # => SELECT "users".* FROM "users" WHERE "users"."name" = 'Oscar' def to_sql @to_sql ||= klass.connection.to_sql(arel, bind_values.dup) end diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 0bd48913e1..84027ea5ae 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -1122,6 +1122,10 @@ class RelationTest < ActiveRecord::TestCase assert_equal authors(:david), Author.order('id DESC , name DESC').last end + def test_update_all_with_blank_argument + assert_raises(ArgumentError) { Comment.update_all({}) } + end + def test_update_all_with_joins comments = Comment.joins(:post).where('posts.id' => posts(:welcome).id) count = comments.count diff --git a/guides/source/4_0_release_notes.textile b/guides/source/4_0_release_notes.textile index 914ba0dd9a..0de8a0a4b7 100644 --- a/guides/source/4_0_release_notes.textile +++ b/guides/source/4_0_release_notes.textile @@ -196,6 +196,37 @@ h5(#actioncontroller_deprecations). Deprecations h4. Action Dispatch +* Add Routing Concerns to declare common routes that can be reused inside others resources and routes. + +Code before: + +<ruby> +resources :messages do + resources :comments +end + +resources :posts do + resources :comments + resources :images, only: :index +end +</ruby> + +Code after: + +<ruby> +concern :commentable do + resources :comments +end + +concern :image_attachable do + resources :images, only: :index +end + +resources :messages, concerns: :commentable + +resources :posts, concerns: [:commentable, :image_attachable] +</ruby> + * Show routes in exception page while debugging a <tt>RoutingError</tt> in development. * Include <tt>mounted_helpers</tt> (helpers for accessing mounted engines) in <tt>ActionDispatch::IntegrationTest</tt> by default. diff --git a/guides/source/contributing_to_ruby_on_rails.textile b/guides/source/contributing_to_ruby_on_rails.textile index 02b4c65d37..65db40e77d 100644 --- a/guides/source/contributing_to_ruby_on_rails.textile +++ b/guides/source/contributing_to_ruby_on_rails.textile @@ -36,11 +36,17 @@ Please don't put "feature request" items into GitHub Issues. If there's a new fe If you'd like feedback on an idea for a feature before doing the work for make a patch, please send an email to the "rails-core mailing list":https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core. You might get no response, which means that everyone is indifferent. You might find someone who's also interested in building that feature. You might get a "This won't be accepted." But it's the proper place to discuss new ideas. GitHub Issues are not a particularly good venue for the sometimes long and involved discussions new features require. -h3. Running the Test Suite +h3. Setting Up a Development Environment To move on from submitting bugs to helping resolve existing issues or contributing your own code to Ruby on Rails, you _must_ be able to run its test suite. In this section of the guide you'll learn how to set up the tests on your own computer. -h4. Install Git +h4. The Easy Way + +The easiest way to get a development environment ready to hack is to use the "Rails development box":https://github.com/rails/rails-dev-box. + +h4. The Hard Way + +h5. Install Git Ruby on Rails uses git for source code control. The "git homepage":http://git-scm.com/ has installation instructions. There are a variety of resources on the net that will help you get familiar with git: @@ -49,7 +55,7 @@ Ruby on Rails uses git for source code control. The "git homepage":http://git-sc * "GitHub":http://help.github.com offers links to a variety of git resources. * "Pro Git":http://progit.org/book/ is an entire book about git with a Creative Commons license. -h4. Clone the Ruby on Rails Repository +h5. Clone the Ruby on Rails Repository Navigate to the folder where you want the Ruby on Rails source code (it will create its own +rails+ subdirectory) and run: @@ -58,7 +64,7 @@ $ git clone git://github.com/rails/rails.git $ cd rails </shell> -h4. Set up and Run the Tests +h5. Set up and Run the Tests The test suite must pass with any submitted code. No matter whether you are writing a new patch, or evaluating someone else's, you need to be able to run the tests. @@ -128,36 +134,17 @@ $ cd actionpack $ bundle exec ruby -Itest test/template/form_helper_test.rb </shell> -h4. Warnings - -The test suite runs with warnings enabled. Ideally, Ruby on Rails should issue no warnings, but there may be a few, as well as some from third-party libraries. Please ignore (or fix!) them, if any, and submit patches that do not issue new warnings. - -As of this writing (December, 2010) they are specially noisy with Ruby 1.9. If you are sure about what you are doing and would like to have a more clear output, there's a way to override the flag: - -<shell> -$ RUBYOPT=-W0 bundle exec rake test -</shell> - -h4. Testing Active Record +h5. Active Record Setup The test suite of Active Record attempts to run four times: once for SQLite3, once for each of the two MySQL gems (+mysql+ and +mysql2+), and once for PostgreSQL. We are going to see now how to set up the environment for them. WARNING: If you're working with Active Record code, you _must_ ensure that the tests pass for at least MySQL, PostgreSQL, and SQLite3. Subtle differences between the various adapters have been behind the rejection of many patches that looked OK when tested only against MySQL. -h5. Database Configuration +h6. Database Configuration The Active Record test suite requires a custom config file: +activerecord/test/config.yml+. An example is provided in +activerecord/test/config.example.yml+ which can be copied and used as needed for your environment. -h5. SQLite3 - -The gem +sqlite3-ruby+ does not belong to the "db" group. Indeed, if you followed the instructions above you're ready. This is how you run the Active Record test suite only for SQLite3: - -<shell> -$ cd activerecord -$ bundle exec rake test_sqlite3 -</shell> - -h5. MySQL and PostgreSQL +h6. MySQL and PostgreSQL To be able to run the suite for MySQL and PostgreSQL we need their gems. Install first the servers, their client libraries, and their development files. In Ubuntu just run @@ -217,6 +204,15 @@ NOTE: You'll see the following warning (or localized warning) during activating If you’re using another database, check the file +activerecord/test/config.yml+ or +activerecord/test/config.example.yml+ for default connection information. You can edit +activerecord/test/config.yml+ to provide different credentials on your machine if you must, but obviously you should not push any such changes back to Rails. +h3. Testing Active Record + +This is how you run the Active Record test suite only for SQLite3: + +<shell> +$ cd activerecord +$ bundle exec rake test_sqlite3 +</shell> + You can now run the tests as you did for +sqlite3+. The tasks are respectively <shell> @@ -225,7 +221,7 @@ test_mysql2 test_postgresql </shell> -As we mentioned before +Finally, <shell> $ bundle exec rake test @@ -241,6 +237,16 @@ $ ARCONN=sqlite3 ruby -Itest test/cases/associations/has_many_associations_test. You can invoke +test_jdbcmysql+, +test_jdbcsqlite3+ or +test_jdbcpostgresql+ also. See the file +activerecord/RUNNING_UNIT_TESTS+ for information on running more targeted database tests, or the file +ci/travis.rb+ for the test suite run by the continuous integration server. +h4. Warnings + +The test suite runs with warnings enabled. Ideally, Ruby on Rails should issue no warnings, but there may be a few, as well as some from third-party libraries. Please ignore (or fix!) them, if any, and submit patches that do not issue new warnings. + +As of this writing (December, 2010) they are specially noisy with Ruby 1.9. If you are sure about what you are doing and would like to have a more clear output, there's a way to override the flag: + +<shell> +$ RUBYOPT=-W0 bundle exec rake test +</shell> + h4. Older Versions of Ruby on Rails If you want to add a fix to older versions of Ruby on Rails, you'll need to set up and switch to your own local tracking branch. Here is an example to switch to the 3-0-stable branch: diff --git a/guides/source/routing.textile b/guides/source/routing.textile index cffbf9bec4..bed7d03e06 100644 --- a/guides/source/routing.textile +++ b/guides/source/routing.textile @@ -273,6 +273,36 @@ The corresponding route helper would be +publisher_magazine_photo_url+, requirin TIP: _Resources should never be nested more than 1 level deep._ +h4. Routing concerns + +Routing Concerns allows you to declare common routes that can be reused inside others resources and routes. + +<ruby> +concern :commentable do + resources :comments +end + +concern :image_attachable do + resources :images, only: :index +end +</ruby> + +These concerns can be used in resources to avoid code duplication and share behavior across routes. + +<ruby> +resources :messages, concerns: :commentable + +resources :posts, concerns: [:commentable, :image_attachable] +</ruby> + +Also you can use them in any place that you want inside the routes, for example in a scope or namespace call: + +<ruby> +namespace :posts do + concerns :commentable +end +</ruby> + h4. Creating Paths and URLs From Objects In addition to using the routing helpers, Rails can also create paths and URLs from an array of parameters. For example, suppose you have this set of routes: diff --git a/railties/lib/rails/console/app.rb b/railties/lib/rails/console/app.rb index ee8bb55f38..2a69c26deb 100644 --- a/railties/lib/rails/console/app.rb +++ b/railties/lib/rails/console/app.rb @@ -1,9 +1,6 @@ require 'active_support/all' -require 'active_support/test_case' require 'action_controller' -# work around the at_exit hook in test/unit, which kills IRB - module Rails module ConsoleMethods # reference the global "app" instance, created on demand. To recreate the |