diff options
14 files changed, 109 insertions, 12 deletions
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 3d3af555c9..40f33a9de0 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -41,6 +41,10 @@ module ActionController autoload :UrlFor end + autoload_under "api" do + autoload :ApiRendering + end + autoload :TestCase, 'action_controller/test_case' autoload :TemplateAssertions, 'action_controller/test_case' diff --git a/actionpack/lib/action_controller/api.rb b/actionpack/lib/action_controller/api.rb index 1a46d49a49..ff12705abe 100644 --- a/actionpack/lib/action_controller/api.rb +++ b/actionpack/lib/action_controller/api.rb @@ -112,7 +112,7 @@ module ActionController UrlFor, Redirecting, - Rendering, + ApiRendering, Renderers::All, ConditionalGet, BasicImplicitRender, diff --git a/actionpack/lib/action_controller/api/api_rendering.rb b/actionpack/lib/action_controller/api/api_rendering.rb new file mode 100644 index 0000000000..3a08d28c39 --- /dev/null +++ b/actionpack/lib/action_controller/api/api_rendering.rb @@ -0,0 +1,14 @@ +module ActionController + module ApiRendering + extend ActiveSupport::Concern + + included do + include Rendering + end + + def render_to_body(options = {}) + _process_options(options) + super + end + end +end diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb index 6e346fadfe..173a14a1d2 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -9,6 +9,13 @@ module ActionController #:nodoc: # @people = Person.all # end # + # That action implicitly responds to all formats, but formats can also be whitelisted: + # + # def index + # @people = Person.all + # respond_to :html, :js + # end + # # Here's the same action, with web-service support baked in: # # def index @@ -16,11 +23,12 @@ module ActionController #:nodoc: # # respond_to do |format| # format.html + # format.js # format.xml { render xml: @people } # end # end # - # What that says is, "if the client wants HTML in response to this action, just respond as we + # What that says is, "if the client wants HTML or JS in response to this action, just respond as we # would have before, but if the client wants XML, return them the list of people in XML format." # (Rails determines the desired response format from the HTTP Accept header submitted by the client.) # @@ -180,9 +188,6 @@ module ActionController #:nodoc: # format.html.none # format.html.phone # this gets rendered # end - # - # Be sure to check the documentation of <tt>ActionController::MimeResponds.respond_to</tt> - # for more examples. def respond_to(*mimes) raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given? diff --git a/actionpack/test/controller/api/renderers_test.rb b/actionpack/test/controller/api/renderers_test.rb index 9405538833..911a8144b2 100644 --- a/actionpack/test/controller/api/renderers_test.rb +++ b/actionpack/test/controller/api/renderers_test.rb @@ -19,6 +19,14 @@ class RenderersApiController < ActionController::API def two render xml: Model.new end + + def plain + render plain: 'Hi from plain', status: 500 + end + + def text + render text: 'Hi from text', status: 500 + end end class RenderersApiTest < ActionController::TestCase @@ -35,4 +43,18 @@ class RenderersApiTest < ActionController::TestCase assert_response :success assert_equal({ a: 'b' }.to_xml, @response.body) end + + def test_render_plain + get :plain + assert_response :internal_server_error + assert_equal('Hi from plain', @response.body) + end + + def test_render_text + assert_deprecated do + get :text + end + assert_response :internal_server_error + assert_equal('Hi from text', @response.body) + end end diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 39e7b42629..0f88791d92 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -18,6 +18,7 @@ module ActiveRecord register_handler(Class, ClassHandler.new(self)) register_handler(Base, BaseHandler.new(self)) register_handler(Range, RangeHandler.new(self)) + register_handler(RangeHandler::RangeWithBinds, RangeHandler.new(self)) register_handler(Relation, RelationHandler.new) register_handler(Array, ArrayHandler.new(self)) register_handler(AssociationQueryValue, AssociationQueryHandler.new(self)) @@ -105,10 +106,23 @@ module ActiveRecord binds += bvs when Relation binds += value.bound_attributes + when Range + first = value.begin + last = value.end + unless first.respond_to?(:infinite?) && first.infinite? + binds << build_bind_param(column_name, first) + first = Arel::Nodes::BindParam.new + end + unless last.respond_to?(:infinite?) && last.infinite? + binds << build_bind_param(column_name, last) + last = Arel::Nodes::BindParam.new + end + + result[column_name] = RangeHandler::RangeWithBinds.new(first, last, value.exclude_end?) else if can_be_bound?(column_name, value) result[column_name] = Arel::Nodes::BindParam.new - binds << Relation::QueryAttribute.new(column_name.to_s, value, table.type(column_name)) + binds << build_bind_param(column_name, value) end end end @@ -145,5 +159,9 @@ module ActiveRecord handler_for(value).is_a?(BasicObjectHandler) && !table.associated_with?(column_name) end + + def build_bind_param(column_name, value) + Relation::QueryAttribute.new(column_name.to_s, value, table.type(column_name)) + end end end diff --git a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb index 1b3849e3ad..306d4694ae 100644 --- a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb +++ b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb @@ -1,12 +1,28 @@ module ActiveRecord class PredicateBuilder class RangeHandler # :nodoc: + RangeWithBinds = Struct.new(:begin, :end, :exclude_end?) + def initialize(predicate_builder) @predicate_builder = predicate_builder end def call(attribute, value) - attribute.between(value) + if value.begin.respond_to?(:infinite?) && value.begin.infinite? + if value.end.respond_to?(:infinite?) && value.end.infinite? + attribute.not_in([]) + elsif value.exclude_end? + attribute.lt(value.end) + else + attribute.lteq(value.end) + end + elsif value.end.respond_to?(:infinite?) && value.end.infinite? + attribute.gteq(value.begin) + elsif value.exclude_end? + attribute.gteq(value.begin).and(attribute.lt(value.end)) + else + attribute.between(value) + end end protected diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md index 0083fc0e6c..60f78d011c 100644 --- a/guides/source/asset_pipeline.md +++ b/guides/source/asset_pipeline.md @@ -1280,8 +1280,9 @@ config.assets.debug = true And in `production.rb`: ```ruby -# Choose the compressors to use (if any) config.assets.js_compressor = -# :uglifier config.assets.css_compressor = :yui +# Choose the compressors to use (if any) +config.assets.js_compressor = :uglifier +# config.assets.css_compressor = :yui # Don't fallback to assets pipeline if a precompiled asset is missed config.assets.compile = false @@ -1290,7 +1291,8 @@ config.assets.compile = false config.assets.digest = true # Precompile additional assets (application.js, application.css, and all -# non-JS/CSS are already added) config.assets.precompile += %w( search.js ) +# non-JS/CSS are already added) +# config.assets.precompile += %w( search.js ) ``` Rails 4 no longer sets default config values for Sprockets in `test.rb`, so diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index eae37f648d..9677ab1583 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -1540,6 +1540,11 @@ This is very similar to the `Article` model that you saw earlier. The difference is the line `belongs_to :article`, which sets up an Active Record _association_. You'll learn a little about associations in the next section of this guide. +The (`:references`) keyword used in the bash command is a special data type for models. +It creates a new column on your database table with the provided model name appended with an `_id` +that can hold integer values. You can get a better understanding after analyzing the +`db/schema.rb` file below. + In addition to the model, Rails has also made a migration to create the corresponding database table: diff --git a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml index b2669a0f79..cdea2fd060 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml @@ -5,7 +5,7 @@ # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. -# You can use `rake secret` to generate a secure secret key. +# You can use `rails secret` to generate a secure secret key. # Make sure the secrets in this file are kept private # if you're sharing your code publicly. diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb index 7d7477de75..0c7a73a54e 100644 --- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb +++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb @@ -337,7 +337,7 @@ task default: :test end def wrap_in_modules(unwrapped_code) - unwrapped_code = "#{unwrapped_code}".strip.gsub(/\W$\n/, '') + unwrapped_code = "#{unwrapped_code}".strip.gsub(/\s$\n/, '') modules.reverse.inject(unwrapped_code) do |content, mod| str = "module #{mod}\n" str += content.lines.map { |line| " #{line}" }.join diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt new file mode 100644 index 0000000000..09aac13f42 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt @@ -0,0 +1,7 @@ +<%= wrap_in_modules <<-rb.strip_heredoc + class ApplicationMailer < ActionMailer::Base + default from: 'from@example.com' + layout 'mailer' + end +rb +%> diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/mailers/.empty_directory b/railties/lib/rails/generators/rails/plugin/templates/app/mailers/.empty_directory deleted file mode 100644 index e69de29bb2..0000000000 --- a/railties/lib/rails/generators/rails/plugin/templates/app/mailers/.empty_directory +++ /dev/null diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index c5723e364d..874bda17b7 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -309,6 +309,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "app/controllers/bukkits/application_controller.rb", /module Bukkits\n class ApplicationController < ActionController::Base/ assert_file "app/models/bukkits/application_record.rb", /module Bukkits\n class ApplicationRecord < ActiveRecord::Base/ assert_file "app/jobs/bukkits/application_job.rb", /module Bukkits\n class ApplicationJob < ActiveJob::Base/ + assert_file "app/mailers/bukkits/application_mailer.rb", /module Bukkits\n class ApplicationMailer < ActionMailer::Base\n default from: 'from@example.com'\n layout 'mailer'\n/ assert_file "app/helpers/bukkits/application_helper.rb", /module Bukkits\n module ApplicationHelper/ assert_file "app/views/layouts/bukkits/application.html.erb" do |contents| assert_match "<title>Bukkits</title>", contents @@ -337,6 +338,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "hyphenated-name/app/controllers/hyphenated/name/application_controller.rb", /module Hyphenated\n module Name\n class ApplicationController < ActionController::Base\n end\n end\nend/ assert_file "hyphenated-name/app/models/hyphenated/name/application_record.rb", /module Hyphenated\n module Name\n class ApplicationRecord < ActiveRecord::Base\n self\.abstract_class = true\n end\n end\nend/ assert_file "hyphenated-name/app/jobs/hyphenated/name/application_job.rb", /module Hyphenated\n module Name\n class ApplicationJob < ActiveJob::Base/ + assert_file "hyphenated-name/app/mailers/hyphenated/name/application_mailer.rb", /module Hyphenated\n module Name\n class ApplicationMailer < ActionMailer::Base\n default from: 'from@example.com'\n layout 'mailer'\n end\n end\nend/ assert_file "hyphenated-name/app/helpers/hyphenated/name/application_helper.rb", /module Hyphenated\n module Name\n module ApplicationHelper\n end\n end\nend/ assert_file "hyphenated-name/app/views/layouts/hyphenated/name/application.html.erb" do |contents| assert_match "<title>Hyphenated name</title>", contents @@ -358,6 +360,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "my_hyphenated-name/app/controllers/my_hyphenated/name/application_controller.rb", /module MyHyphenated\n module Name\n class ApplicationController < ActionController::Base\n end\n end\nend/ assert_file "my_hyphenated-name/app/models/my_hyphenated/name/application_record.rb", /module MyHyphenated\n module Name\n class ApplicationRecord < ActiveRecord::Base\n self\.abstract_class = true\n end\n end\nend/ assert_file "my_hyphenated-name/app/jobs/my_hyphenated/name/application_job.rb", /module MyHyphenated\n module Name\n class ApplicationJob < ActiveJob::Base/ + assert_file "my_hyphenated-name/app/mailers/my_hyphenated/name/application_mailer.rb", /module MyHyphenated\n module Name\n class ApplicationMailer < ActionMailer::Base\n default from: 'from@example.com'\n layout 'mailer'\n end\n end\nend/ assert_file "my_hyphenated-name/app/helpers/my_hyphenated/name/application_helper.rb", /module MyHyphenated\n module Name\n module ApplicationHelper\n end\n end\nend/ assert_file "my_hyphenated-name/app/views/layouts/my_hyphenated/name/application.html.erb" do |contents| assert_match "<title>My hyphenated name</title>", contents @@ -379,6 +382,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "deep-hyphenated-name/app/controllers/deep/hyphenated/name/application_controller.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationController < ActionController::Base\n end\n end\n end\nend/ assert_file "deep-hyphenated-name/app/models/deep/hyphenated/name/application_record.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationRecord < ActiveRecord::Base\n self\.abstract_class = true\n end\n end\n end\nend/ assert_file "deep-hyphenated-name/app/jobs/deep/hyphenated/name/application_job.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationJob < ActiveJob::Base/ + assert_file "deep-hyphenated-name/app/mailers/deep/hyphenated/name/application_mailer.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationMailer < ActionMailer::Base\n default from: 'from@example.com'\n layout 'mailer'\n end\n end\n end\nend/ assert_file "deep-hyphenated-name/app/helpers/deep/hyphenated/name/application_helper.rb", /module Deep\n module Hyphenated\n module Name\n module ApplicationHelper\n end\n end\n end\nend/ assert_file "deep-hyphenated-name/app/views/layouts/deep/hyphenated/name/application.html.erb" do |contents| assert_match "<title>Deep hyphenated name</title>", contents |