aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RAILS_VERSION2
-rw-r--r--actionmailer/lib/action_mailer/collector.rb4
-rw-r--r--actionmailer/lib/action_mailer/version.rb4
-rw-r--r--actionpack/CHANGELOG.md4
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb2
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb2
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb3
-rw-r--r--actionpack/lib/action_pack/version.rb4
-rw-r--r--actionpack/lib/action_view/lookup_context.rb14
-rw-r--r--actionpack/lib/action_view/renderer/abstract_renderer.rb2
-rw-r--r--actionpack/lib/action_view/renderer/template_renderer.rb3
-rw-r--r--actionpack/lib/action_view/template.rb1
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb4
-rw-r--r--actionpack/test/controller/base_test.rb6
-rw-r--r--actionpack/test/controller/content_type_test.rb4
-rw-r--r--actionpack/test/dispatch/routing_test.rb1
-rw-r--r--actionpack/test/fixtures/test/one.html.erb1
-rw-r--r--actionpack/test/template/lookup_context_test.rb4
-rw-r--r--actionpack/test/template/record_tag_helper_test.rb41
-rw-r--r--actionpack/test/template/render_test.rb7
-rw-r--r--actionpack/test/template/template_test.rb2
-rw-r--r--activemodel/lib/active_model/attribute_methods.rb2
-rw-r--r--activemodel/lib/active_model/version.rb4
-rw-r--r--activerecord/activerecord.gemspec2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb16
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb14
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb20
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb71
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb14
-rw-r--r--activerecord/lib/active_record/counter_cache.rb2
-rw-r--r--activerecord/lib/active_record/railties/databases.rake2
-rw-r--r--activerecord/lib/active_record/relation.rb3
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb2
-rw-r--r--activerecord/lib/active_record/version.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_test.rb10
-rw-r--r--activeresource/lib/active_resource/version.rb4
-rw-r--r--activesupport/lib/active_support/version.rb4
-rw-r--r--activesupport/test/core_ext/range_ext_test.rb2
-rw-r--r--railties/lib/rails/version.rb4
-rw-r--r--version.rb4
42 files changed, 176 insertions, 127 deletions
diff --git a/RAILS_VERSION b/RAILS_VERSION
index e4604e3afd..183633372e 100644
--- a/RAILS_VERSION
+++ b/RAILS_VERSION
@@ -1 +1 @@
-3.2.1
+3.2.2.rc1
diff --git a/actionmailer/lib/action_mailer/collector.rb b/actionmailer/lib/action_mailer/collector.rb
index d03e085e83..17b22aea2a 100644
--- a/actionmailer/lib/action_mailer/collector.rb
+++ b/actionmailer/lib/action_mailer/collector.rb
@@ -22,9 +22,9 @@ module ActionMailer #:nodoc:
def custom(mime, options={})
options.reverse_merge!(:content_type => mime.to_s)
- @context.freeze_formats([mime.to_sym])
+ @context.formats = [mime.to_sym]
options[:body] = block_given? ? yield : @default_render.call
@responses << options
end
end
-end \ No newline at end of file
+end
diff --git a/actionmailer/lib/action_mailer/version.rb b/actionmailer/lib/action_mailer/version.rb
index 5817ed363d..fa416a0360 100644
--- a/actionmailer/lib/action_mailer/version.rb
+++ b/actionmailer/lib/action_mailer/version.rb
@@ -2,8 +2,8 @@ module ActionMailer
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 1
- PRE = nil
+ TINY = 2
+ PRE = "rc1"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 398cdabca2..7873c23030 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,5 +1,9 @@
## Rails 3.2.2 (unreleased) ##
+* Format lookup for partials is derived from the format in which the template is being rendered. Closes #5025 part 2 *Santiago Pastorino*
+
+* Use the right format when a partial is missing. Closes #5025. *Santiago Pastorino*
+
* Default responder will now always use your overridden block in `respond_with` to render your response. *Prem Sichanugrist*
* check_box helper with :disabled => true will generate a disabled hidden field to conform with the HTML convention where disabled fields are not submitted with the form.
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index 80ecc16d53..55de7e7d8e 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -280,7 +280,7 @@ module ActionController #:nodoc:
if format
self.content_type ||= format.to_s
- lookup_context.freeze_formats([format.to_sym])
+ lookup_context.formats = [format.to_sym]
collector
else
head :not_acceptable
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index 70fd79bb8b..02a2e3db86 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -14,7 +14,7 @@ module ActionController
def render(*args) #:nodoc:
raise ::AbstractController::DoubleRenderError if response_body
super
- self.content_type ||= Mime[formats.first].to_s
+ self.content_type ||= Mime[lookup_context.rendered_format].to_s
response_body
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 33eb7b0746..a78e1e13b0 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -267,8 +267,7 @@ module ActionDispatch
def eval_block(block)
if block.arity == 1
raise "You are using the old router DSL which has been removed in Rails 3.1. " <<
- "Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/ " <<
- "or add the rails_legacy_mapper gem to your Gemfile"
+ "Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/"
end
mapper = Mapper.new(self)
if default_scope
diff --git a/actionpack/lib/action_pack/version.rb b/actionpack/lib/action_pack/version.rb
index a6041385f8..1f501a3c52 100644
--- a/actionpack/lib/action_pack/version.rb
+++ b/actionpack/lib/action_pack/version.rb
@@ -2,8 +2,8 @@ module ActionPack
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 1
- PRE = nil
+ TINY = 2
+ PRE = "rc1"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb
index 3bb2b98e48..33b508e9b5 100644
--- a/actionpack/lib/action_view/lookup_context.rb
+++ b/actionpack/lib/action_view/lookup_context.rb
@@ -10,7 +10,7 @@ module ActionView
# generate a key, given to view paths, used in the resolver cache lookup. Since
# this key is generated just once during the request, it speeds up all cache accesses.
class LookupContext #:nodoc:
- attr_accessor :prefixes
+ attr_accessor :prefixes, :rendered_format
mattr_accessor :fallbacks
@@fallbacks = FallbackFileSystemResolver.instances
@@ -180,23 +180,15 @@ module ActionView
def initialize(view_paths, details = {}, prefixes = [])
@details, @details_key = {}, nil
- @frozen_formats, @skip_default_locale = false, false
+ @skip_default_locale = false
@cache = true
@prefixes = prefixes
+ @rendered_format = nil
self.view_paths = view_paths
initialize_details(details)
end
- # Freeze the current formats in the lookup context. By freezing them, you
- # that next template lookups are not going to modify the formats. The con
- # use this, to ensure that formats won't be further modified (as it does
- def freeze_formats(formats, unless_frozen=false) #:nodoc:
- return if unless_frozen && @frozen_formats
- self.formats = formats
- @frozen_formats = true
- end
-
# Override formats= to expand ["*/*"] values and automatically
# add :html as fallback to :js.
def formats=(values)
diff --git a/actionpack/lib/action_view/renderer/abstract_renderer.rb b/actionpack/lib/action_view/renderer/abstract_renderer.rb
index c0936441ac..0b5d3785d4 100644
--- a/actionpack/lib/action_view/renderer/abstract_renderer.rb
+++ b/actionpack/lib/action_view/renderer/abstract_renderer.rb
@@ -1,7 +1,7 @@
module ActionView
class AbstractRenderer #:nodoc:
delegate :find_template, :template_exists?, :with_fallbacks, :update_details,
- :with_layout_format, :formats, :freeze_formats, :to => :@lookup_context
+ :with_layout_format, :formats, :to => :@lookup_context
def initialize(lookup_context)
@lookup_context = lookup_context
diff --git a/actionpack/lib/action_view/renderer/template_renderer.rb b/actionpack/lib/action_view/renderer/template_renderer.rb
index adf87a3f7e..ddde990b72 100644
--- a/actionpack/lib/action_view/renderer/template_renderer.rb
+++ b/actionpack/lib/action_view/renderer/template_renderer.rb
@@ -8,7 +8,8 @@ module ActionView
@details = extract_details(options)
extract_format(options[:file] || options[:template], @details)
template = determine_template(options)
- freeze_formats(template.formats, true)
+ @lookup_context.rendered_format ||= template.formats.first
+ @lookup_context.formats = template.formats
render_template(template, options[:layout], options[:locals])
end
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index af6e5d0645..eac6287b0b 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -164,7 +164,6 @@ module ActionView
pieces = @virtual_path.split("/")
name = pieces.pop
partial = !!name.sub!(/^_/, "")
- lookup.formats = @formats
lookup.disable_cache do
lookup.find_template(name, [ pieces.join('/') ], partial, @locals)
end
diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index 25f26dd609..ea495ea9ca 100644
--- a/actionpack/lib/action_view/template/handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
@@ -44,10 +44,6 @@ module ActionView
class_attribute :erb_trim_mode
self.erb_trim_mode = '-'
- # Default format used by ERB.
- class_attribute :default_format
- self.default_format = Mime::HTML
-
# Default implementation used.
class_attribute :erb_implementation
self.erb_implementation = Erubis
diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb
index 777ca11d85..6f76ab9596 100644
--- a/actionpack/test/controller/base_test.rb
+++ b/actionpack/test/controller/base_test.rb
@@ -167,7 +167,7 @@ class PerformActionTest < ActionController::TestCase
def test_get_on_priv_should_show_selector
use_controller MethodMissingController
- assert_deprecated /Using `method_missing` to handle .* use `action_missing` instead/ do
+ assert_deprecated(/Using `method_missing` to handle .* use `action_missing` instead/) do
get :shouldnt_be_called
end
assert_response :success
@@ -178,7 +178,7 @@ class PerformActionTest < ActionController::TestCase
use_controller MethodMissingController
assert !@controller.__send__(:action_method?, 'method_missing')
- assert_deprecated /Using `method_missing` to handle .* use `action_missing` instead/ do
+ assert_deprecated(/Using `method_missing` to handle .* use `action_missing` instead/) do
get :method_missing
end
assert_response :success
@@ -187,7 +187,7 @@ class PerformActionTest < ActionController::TestCase
def test_method_missing_should_recieve_symbol
use_controller AnotherMethodMissingController
- assert_deprecated /Using `method_missing` to handle .* use `action_missing` instead/ do
+ assert_deprecated(/Using `method_missing` to handle .* use `action_missing` instead/) do
get :some_action
end
assert_kind_of NameError, @controller._exception
diff --git a/actionpack/test/controller/content_type_test.rb b/actionpack/test/controller/content_type_test.rb
index d0dabb29ca..e8e445532a 100644
--- a/actionpack/test/controller/content_type_test.rb
+++ b/actionpack/test/controller/content_type_test.rb
@@ -70,7 +70,7 @@ class ContentTypeTest < ActionController::TestCase
end
def test_render_changed_charset_default
- assert_deprecated /Setting default charset at controller.*config\.action_dispatch\.default_charset/ do
+ assert_deprecated(/Setting default charset at controller.*config\.action_dispatch\.default_charset/) do
begin
OldContentTypeController.default_charset = "utf-16"
get :render_defaults
@@ -111,7 +111,7 @@ class ContentTypeTest < ActionController::TestCase
end
def test_nil_default_for_erb
- assert_deprecated /Setting default charset at controller.*config\.action_dispatch\.default_charset/ do
+ assert_deprecated(/Setting default charset at controller.*config\.action_dispatch\.default_charset/) do
begin
OldContentTypeController.default_charset = nil
get :render_default_for_erb
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 3922e3628d..b96987410f 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -2574,7 +2574,6 @@ class TestUnicodePaths < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
match "/#{Rack::Utils.escape("ほげ")}" => lambda { |env|
- path_params = env['action_dispatch.request.path_parameters']
[200, { 'Content-Type' => 'text/plain' }, []]
}, :as => :unicode_path
end
diff --git a/actionpack/test/fixtures/test/one.html.erb b/actionpack/test/fixtures/test/one.html.erb
new file mode 100644
index 0000000000..0151874809
--- /dev/null
+++ b/actionpack/test/fixtures/test/one.html.erb
@@ -0,0 +1 @@
+<%= render :partial => "test/two" %> world \ No newline at end of file
diff --git a/actionpack/test/template/lookup_context_test.rb b/actionpack/test/template/lookup_context_test.rb
index c65f707da0..96b14a0acd 100644
--- a/actionpack/test/template/lookup_context_test.rb
+++ b/actionpack/test/template/lookup_context_test.rb
@@ -78,9 +78,9 @@ class LookupContextTest < ActiveSupport::TestCase
end
test "found templates respects given formats if one cannot be found from template or handler" do
- ActionView::Template::Handlers::ERB.expects(:default_format).returns(nil)
+ ActionView::Template::Handlers::Builder.expects(:default_format).returns(nil)
@lookup_context.formats = [:text]
- template = @lookup_context.find("hello_world", %w(test))
+ template = @lookup_context.find("hello", %w(test))
assert_equal [:text], template.formats
end
diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb
index ec777d15c4..80d6f130ed 100644
--- a/actionpack/test/template/record_tag_helper_test.rb
+++ b/actionpack/test/template/record_tag_helper_test.rb
@@ -1,15 +1,15 @@
require 'abstract_unit'
require 'controller/fake_models'
-class Post
+class RecordTagPost
extend ActiveModel::Naming
include ActiveModel::Conversion
- attr_writer :id, :body
+ attr_writer :id, :body, :persisted
def initialize
@id = nil
@body = nil
- super
+ @persisted = false
end
def id
@@ -17,8 +17,11 @@ class Post
end
def body
- super || @body || "What a wonderful world!"
+ @body || "What a wonderful world!"
end
+
+ def persisted?; @persisted end
+
end
class RecordTagHelperTest < ActionView::TestCase
@@ -28,30 +31,30 @@ class RecordTagHelperTest < ActionView::TestCase
def setup
super
- @post = Post.new
+ @post = RecordTagPost.new
@post.persisted = true
end
def test_content_tag_for
- expected = %(<li class="post bar" id="post_45"></li>)
+ expected = %(<li class="record_tag_post bar" id="record_tag_post_45"></li>)
actual = content_tag_for(:li, @post, :class => 'bar') { }
assert_dom_equal expected, actual
end
def test_content_tag_for_prefix
- expected = %(<ul class="archived_post" id="archived_post_45"></ul>)
+ expected = %(<ul class="archived_record_tag_post" id="archived_record_tag_post_45"></ul>)
actual = content_tag_for(:ul, @post, :archived) { }
assert_dom_equal expected, actual
end
def test_content_tag_for_with_extra_html_tags
- expected = %(<tr class="post bar" id="post_45" style='background-color: #f0f0f0'></tr>)
+ expected = %(<tr class="record_tag_post bar" id="record_tag_post_45" style='background-color: #f0f0f0'></tr>)
actual = content_tag_for(:tr, @post, {:class => "bar", :style => "background-color: #f0f0f0"}) { }
assert_dom_equal expected, actual
end
def test_block_not_in_erb_multiple_calls
- expected = %(<div class="post bar" id="post_45">#{@post.body}</div>)
+ expected = %(<div class="record_tag_post bar" id="record_tag_post_45">#{@post.body}</div>)
actual = div_for(@post, :class => "bar") { @post.body }
assert_dom_equal expected, actual
actual = div_for(@post, :class => "bar") { @post.body }
@@ -59,29 +62,29 @@ class RecordTagHelperTest < ActionView::TestCase
end
def test_block_works_with_content_tag_for_in_erb
- expected = %(<tr class="post" id="post_45">#{@post.body}</tr>)
+ expected = %(<tr class="record_tag_post" id="record_tag_post_45">#{@post.body}</tr>)
actual = render_erb("<%= content_tag_for(:tr, @post) do %><%= @post.body %><% end %>")
assert_dom_equal expected, actual
end
def test_div_for_in_erb
- expected = %(<div class="post bar" id="post_45">#{@post.body}</div>)
+ expected = %(<div class="record_tag_post bar" id="record_tag_post_45">#{@post.body}</div>)
actual = render_erb("<%= div_for(@post, :class => 'bar') do %><%= @post.body %><% end %>")
assert_dom_equal expected, actual
end
def test_content_tag_for_collection
- post_1 = Post.new.tap { |post| post.id = 101; post.body = "Hello!"; post.persisted = true }
- post_2 = Post.new.tap { |post| post.id = 102; post.body = "World!"; post.persisted = true }
- expected = %(<li class="post" id="post_101">Hello!</li>\n<li class="post" id="post_102">World!</li>)
+ post_1 = RecordTagPost.new.tap { |post| post.id = 101; post.body = "Hello!"; post.persisted = true }
+ post_2 = RecordTagPost.new.tap { |post| post.id = 102; post.body = "World!"; post.persisted = true }
+ expected = %(<li class="record_tag_post" id="record_tag_post_101">Hello!</li>\n<li class="record_tag_post" id="record_tag_post_102">World!</li>)
actual = content_tag_for(:li, [post_1, post_2]) { |post| concat post.body }
assert_dom_equal expected, actual
end
def test_div_for_collection
- post_1 = Post.new.tap { |post| post.id = 101; post.body = "Hello!"; post.persisted = true }
- post_2 = Post.new.tap { |post| post.id = 102; post.body = "World!"; post.persisted = true }
- expected = %(<div class="post" id="post_101">Hello!</div>\n<div class="post" id="post_102">World!</div>)
+ post_1 = RecordTagPost.new.tap { |post| post.id = 101; post.body = "Hello!"; post.persisted = true }
+ post_2 = RecordTagPost.new.tap { |post| post.id = 102; post.body = "World!"; post.persisted = true }
+ expected = %(<div class="record_tag_post" id="record_tag_post_101">Hello!</div>\n<div class="record_tag_post" id="record_tag_post_102">World!</div>)
actual = div_for([post_1, post_2]) { |post| concat post.body }
assert_dom_equal expected, actual
end
@@ -92,8 +95,8 @@ class RecordTagHelperTest < ActionView::TestCase
end
def test_content_tag_for_collection_is_html_safe
- post_1 = Post.new.tap { |post| post.id = 101; post.body = "Hello!"; post.persisted = true }
- post_2 = Post.new.tap { |post| post.id = 102; post.body = "World!"; post.persisted = true }
+ post_1 = RecordTagPost.new.tap { |post| post.id = 101; post.body = "Hello!"; post.persisted = true }
+ post_2 = RecordTagPost.new.tap { |post| post.id = 102; post.body = "World!"; post.persisted = true }
result = content_tag_for(:li, [post_1, post_2]) { |post| concat post.body }
assert result.html_safe?
end
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index 4eb3754a50..503bbb207e 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -51,9 +51,14 @@ module RenderTestCases
assert_match "<error>No Comment</error>", @view.render(:template => "comments/empty", :formats => [:xml])
end
+ def test_render_partial_implicitly_use_format_of_the_rendered_template
+ @view.lookup_context.formats = [:json]
+ assert_equal "Hello world", @view.render(:template => "test/one", :formats => [:html])
+ end
+
def test_render_template_with_a_missing_partial_of_another_format
+ @view.lookup_context.formats = [:html]
assert_raise ActionView::Template::Error, "Missing partial /missing with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder]}" do
- @view.lookup_context.freeze_formats([:html])
@view.render(:template => "with_format", :formats => [:json])
end
end
diff --git a/actionpack/test/template/template_test.rb b/actionpack/test/template/template_test.rb
index 836c5c7586..dd45a08b01 100644
--- a/actionpack/test/template/template_test.rb
+++ b/actionpack/test/template/template_test.rb
@@ -12,7 +12,7 @@ class TestERBTemplate < ActiveSupport::TestCase
def find_template(*args)
end
- attr_writer :formats
+ attr_accessor :formats
end
class Context
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb
index 91c6b9721c..f033a94c02 100644
--- a/activemodel/lib/active_model/attribute_methods.rb
+++ b/activemodel/lib/active_model/attribute_methods.rb
@@ -263,7 +263,7 @@ module ActiveModel
unless instance_method_already_implemented?(method_name)
generate_method = "define_method_#{matcher.method_missing_target}"
- if respond_to?(generate_method)
+ if respond_to?(generate_method, true)
send(generate_method, attr_name)
else
define_optimized_call generated_attribute_methods, method_name, matcher.method_missing_target, attr_name.to_s
diff --git a/activemodel/lib/active_model/version.rb b/activemodel/lib/active_model/version.rb
index 91b566c434..c7983a89f3 100644
--- a/activemodel/lib/active_model/version.rb
+++ b/activemodel/lib/active_model/version.rb
@@ -2,8 +2,8 @@ module ActiveModel
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 1
- PRE = nil
+ TINY = 2
+ PRE = "rc1"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/activerecord/activerecord.gemspec b/activerecord/activerecord.gemspec
index 74d50ba155..384dcd85b8 100644
--- a/activerecord/activerecord.gemspec
+++ b/activerecord/activerecord.gemspec
@@ -21,6 +21,6 @@ Gem::Specification.new do |s|
s.add_dependency('activesupport', version)
s.add_dependency('activemodel', version)
- s.add_dependency('arel', '~> 3.0.0')
+ s.add_dependency('arel', '~> 3.0.2')
s.add_dependency('tzinfo', '~> 0.3.29')
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index eb8cff9610..db99c3fbef 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -2,9 +2,11 @@ module ActiveRecord
module ConnectionAdapters # :nodoc:
module DatabaseStatements
# Converts an arel AST to SQL
- def to_sql(arel)
+ def to_sql(arel, binds = [])
if arel.respond_to?(:ast)
- visitor.accept(arel.ast)
+ visitor.accept(arel.ast) do
+ quote(*binds.shift.reverse)
+ end
else
arel
end
@@ -13,7 +15,7 @@ module ActiveRecord
# Returns an array of record hashes with the column names as keys and
# column values as values.
def select_all(arel, name = nil, binds = [])
- select(to_sql(arel), name, binds)
+ select(to_sql(arel, binds), name, binds)
end
# Returns a record hash with the column names as keys and column values
@@ -33,7 +35,7 @@ module ActiveRecord
# Returns an array of the values of the first column in a select:
# select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
def select_values(arel, name = nil)
- result = select_rows(to_sql(arel), name)
+ result = select_rows(to_sql(arel, []), name)
result.map { |v| v[0] }
end
@@ -84,19 +86,19 @@ module ActiveRecord
# If the next id was calculated in advance (as in Oracle), it should be
# passed in as +id_value+.
def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
- sql, binds = sql_for_insert(to_sql(arel), pk, id_value, sequence_name, binds)
+ sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
value = exec_insert(sql, name, binds)
id_value || last_inserted_id(value)
end
# Executes the update statement and returns the number of rows affected.
def update(arel, name = nil, binds = [])
- exec_update(to_sql(arel), name, binds)
+ exec_update(to_sql(arel, binds), name, binds)
end
# Executes the delete statement and returns the number of rows affected.
def delete(arel, name = nil, binds = [])
- exec_delete(to_sql(arel), name, binds)
+ exec_delete(to_sql(arel, binds), name, binds)
end
# Checks whether there is currently no transaction active. This is done
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
index 52f09efd53..06e4c7a6e0 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
@@ -57,7 +57,7 @@ module ActiveRecord
def select_all(arel, name = nil, binds = [])
if @query_cache_enabled
- sql = to_sql(arel)
+ sql = to_sql(arel, binds)
cache_sql(sql, binds) { super(sql, name, binds) }
else
super
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 5a2493f69d..7d024a5549 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -158,7 +158,7 @@ module ActiveRecord
# Returns a bind substitution value given a +column+ and list of current
# +binds+
def substitute_at(column, index)
- Arel.sql '?'
+ Arel::Nodes::BindParam.new '?'
end
# REFERENTIAL INTEGRITY ====================================
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 9d9dbcc355..729e20d707 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/object/blank'
+require 'arel/visitors/bind_visitor'
module ActiveRecord
module ConnectionAdapters
@@ -122,12 +123,21 @@ module ActiveRecord
:boolean => { :name => "tinyint", :limit => 1 }
}
+ class BindSubstitution < Arel::Visitors::MySQL # :nodoc:
+ include Arel::Visitors::BindVisitor
+ end
+
# FIXME: Make the first parameter more similar for the two adapters
def initialize(connection, logger, connection_options, config)
super(connection, logger)
@connection_options, @config = connection_options, config
@quoted_column_names, @quoted_table_names = {}, {}
- @visitor = Arel::Visitors::MySQL.new self
+
+ if config.fetch(:prepared_statements) { true }
+ @visitor = Arel::Visitors::MySQL.new self
+ else
+ @visitor = BindSubstitution.new self
+ end
end
def adapter_name #:nodoc:
@@ -427,7 +437,7 @@ module ActiveRecord
table, arguments = args.shift, args
method = :"#{command}_sql"
- if respond_to?(method)
+ if respond_to?(method, true)
send(method, table, *arguments)
else
raise "Unknown method called : #{method}(#{arguments.inspect})"
diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index 626571a948..d95f3fbc1f 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -32,6 +32,7 @@ module ActiveRecord
def initialize(connection, logger, connection_options, config)
super
+ @visitor = BindSubstitution.new self
configure_connection
end
@@ -65,10 +66,6 @@ module ActiveRecord
@connection.escape(string)
end
- def substitute_at(column, index)
- Arel.sql "\0"
- end
-
# CONNECTION MANAGEMENT ====================================
def active?
@@ -98,7 +95,7 @@ module ActiveRecord
# DATABASE STATEMENTS ======================================
def explain(arel, binds = [])
- sql = "EXPLAIN #{to_sql(arel)}"
+ sql = "EXPLAIN #{to_sql(arel, binds.dup)}"
start = Time.now
result = exec_query(sql, 'EXPLAIN', binds)
elapsed = Time.now - start
@@ -224,8 +221,7 @@ module ActiveRecord
# Returns an array of record hashes with the column names as keys and
# column values as values.
def select(sql, name = nil, binds = [])
- binds = binds.dup
- exec_query(sql.gsub("\0") { quote(*binds.shift.reverse) }, name).to_a
+ exec_query(sql, name).to_a
end
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
@@ -235,17 +231,11 @@ module ActiveRecord
alias :create :insert_sql
def exec_insert(sql, name, binds)
- binds = binds.dup
-
- # Pretend to support bind parameters
- execute sql.gsub("\0") { quote(*binds.shift.reverse) }, name
+ execute to_sql(sql, binds), name
end
def exec_delete(sql, name, binds)
- binds = binds.dup
-
- # Pretend to support bind parameters
- execute sql.gsub("\0") { quote(*binds.shift.reverse) }, name
+ execute to_sql(sql, binds), name
@connection.affected_rows
end
alias :exec_update :exec_delete
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 6b742ed858..470c9c6ef3 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -1,6 +1,7 @@
require 'active_record/connection_adapters/abstract_adapter'
require 'active_support/core_ext/object/blank'
require 'active_record/connection_adapters/statement_pool'
+require 'arel/visitors/bind_visitor'
# Make sure we're using pg high enough for PGResult#values
gem 'pg', '~> 0.11'
@@ -303,11 +304,23 @@ module ActiveRecord
end
end
+ class BindSubstitution < Arel::Visitors::PostgreSQL # :nodoc:
+ include Arel::Visitors::BindVisitor
+ end
+
# Initializes and connects a PostgreSQL adapter.
def initialize(connection, logger, connection_parameters, config)
super(connection, logger)
+
+ if config.fetch(:prepared_statements) { true }
+ @visitor = Arel::Visitors::PostgreSQL.new self
+ else
+ @visitor = BindSubstitution.new self
+ end
+
+ connection_parameters.delete :prepared_statements
+
@connection_parameters, @config = connection_parameters, config
- @visitor = Arel::Visitors::PostgreSQL.new self
# @local_tz is initialized as nil to avoid warnings when connect tries to use it
@local_tz = nil
@@ -520,7 +533,7 @@ module ActiveRecord
# DATABASE STATEMENTS ======================================
def explain(arel, binds = [])
- sql = "EXPLAIN #{to_sql(arel)}"
+ sql = "EXPLAIN #{to_sql(arel, binds)}"
ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
end
@@ -642,7 +655,7 @@ module ActiveRecord
end
def substitute_at(column, index)
- Arel.sql("$#{index + 1}")
+ Arel::Nodes::BindParam.new "$#{index + 1}"
end
def exec_query(sql, name = 'SQL', binds = [])
@@ -932,26 +945,46 @@ module ActiveRecord
def pk_and_sequence_for(table) #:nodoc:
# First try looking for a sequence with a dependency on the
# given table's primary key.
- result = exec_query(<<-end_sql, 'SCHEMA').rows.first
- SELECT attr.attname, ns.nspname, seq.relname
- FROM pg_class seq
- INNER JOIN pg_depend dep ON seq.oid = dep.objid
- INNER JOIN pg_attribute attr ON attr.attrelid = dep.refobjid AND attr.attnum = dep.refobjsubid
- INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[1]
- INNER JOIN pg_namespace ns ON seq.relnamespace = ns.oid
- WHERE seq.relkind = 'S'
- AND cons.contype = 'p'
- AND dep.refobjid = '#{quote_table_name(table)}'::regclass
+ result = query(<<-end_sql, 'PK and serial sequence')[0]
+ SELECT attr.attname, seq.relname
+ FROM pg_class seq,
+ pg_attribute attr,
+ pg_depend dep,
+ pg_namespace name,
+ pg_constraint cons
+ WHERE seq.oid = dep.objid
+ AND seq.relkind = 'S'
+ AND attr.attrelid = dep.refobjid
+ AND attr.attnum = dep.refobjsubid
+ AND attr.attrelid = cons.conrelid
+ AND attr.attnum = cons.conkey[1]
+ AND cons.contype = 'p'
+ AND dep.refobjid = '#{quote_table_name(table)}'::regclass
end_sql
- # [primary_key, sequence]
- if result.second == 'public' then
- sequence = result.last
- else
- sequence = result.second+'.'+result.last
+ if result.nil? or result.empty?
+ # If that fails, try parsing the primary key's default value.
+ # Support the 7.x and 8.0 nextval('foo'::text) as well as
+ # the 8.1+ nextval('foo'::regclass).
+ result = query(<<-end_sql, 'PK and custom sequence')[0]
+ SELECT attr.attname,
+ CASE
+ WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
+ substr(split_part(def.adsrc, '''', 2),
+ strpos(split_part(def.adsrc, '''', 2), '.')+1)
+ ELSE split_part(def.adsrc, '''', 2)
+ END
+ FROM pg_class t
+ JOIN pg_attribute attr ON (t.oid = attrelid)
+ JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
+ JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
+ WHERE t.oid = '#{quote_table_name(table)}'::regclass
+ AND cons.contype = 'p'
+ AND def.adsrc ~* 'nextval'
+ end_sql
end
- [result.first, sequence]
+ [result.first, result.last]
rescue
nil
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 56ea1a2841..ad0d0d7170 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -1,6 +1,7 @@
require 'active_record/connection_adapters/abstract_adapter'
require 'active_record/connection_adapters/statement_pool'
require 'active_support/core_ext/string/encoding'
+require 'arel/visitors/bind_visitor'
module ActiveRecord
module ConnectionAdapters #:nodoc:
@@ -69,12 +70,21 @@ module ActiveRecord
end
end
+ class BindSubstitution < Arel::Visitors::SQLite # :nodoc:
+ include Arel::Visitors::BindVisitor
+ end
+
def initialize(connection, logger, config)
super(connection, logger)
@statements = StatementPool.new(@connection,
config.fetch(:statement_limit) { 1000 })
@config = config
- @visitor = Arel::Visitors::SQLite.new self
+
+ if config.fetch(:prepared_statements) { true }
+ @visitor = Arel::Visitors::SQLite.new self
+ else
+ @visitor = BindSubstitution.new self
+ end
end
def adapter_name #:nodoc:
@@ -210,7 +220,7 @@ module ActiveRecord
# DATABASE STATEMENTS ======================================
def explain(arel, binds = [])
- sql = "EXPLAIN QUERY PLAN #{to_sql(arel)}"
+ sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
end
diff --git a/activerecord/lib/active_record/counter_cache.rb b/activerecord/lib/active_record/counter_cache.rb
index c9c46b8d4f..ee0b0c7fab 100644
--- a/activerecord/lib/active_record/counter_cache.rb
+++ b/activerecord/lib/active_record/counter_cache.rb
@@ -19,7 +19,7 @@ module ActiveRecord
counters.each do |association|
has_many_association = reflect_on_association(association.to_sym)
- expected_name = if has_many_association.options[:as]
+ if has_many_association.options[:as]
has_many_association.options[:as].to_s.classify
else
self.name
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index 2df83514bd..b94df4262a 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -424,7 +424,7 @@ db_namespace = namespace :db do
end
when /postgresql/
set_psql_env(abcs[env])
- `psql -f "#{filename}" #{abcs[env]['database']} #{abcs[env]['template']}`
+ `psql -f "#{filename}" #{abcs[env]['database']}`
when /sqlite/
dbfile = abcs[env]['database']
`sqlite3 #{dbfile} < "#{filename}"`
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 30f1824f0f..8c56072337 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -77,6 +77,7 @@ module ActiveRecord
end
def initialize_copy(other)
+ @bind_values = @bind_values.dup
reset
end
@@ -453,7 +454,7 @@ module ActiveRecord
end
def to_sql
- @to_sql ||= klass.connection.to_sql(arel)
+ @to_sql ||= klass.connection.to_sql(arel, @bind_values.dup)
end
def where_values_hash
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 3015b4b40d..0305e561c8 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -208,7 +208,7 @@ module ActiveRecord
def find_with_associations
join_dependency = construct_join_dependency_for_association_find
relation = construct_relation_for_association_find(join_dependency)
- rows = connection.select_all(relation, 'SQL', relation.bind_values)
+ rows = connection.select_all(relation, 'SQL', relation.bind_values.dup)
join_dependency.instantiate(rows)
rescue ThrowResult
[]
diff --git a/activerecord/lib/active_record/version.rb b/activerecord/lib/active_record/version.rb
index 92e3b362c8..d34726de44 100644
--- a/activerecord/lib/active_record/version.rb
+++ b/activerecord/lib/active_record/version.rb
@@ -2,8 +2,8 @@ module ActiveRecord
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 1
- PRE = nil
+ TINY = 2
+ PRE = "rc1"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb
index 18670b4177..18c81d2b09 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb
@@ -24,6 +24,8 @@ class SchemaTest < ActiveRecord::TestCase
'moment timestamp without time zone default now()'
]
PK_TABLE_NAME = 'table_with_pk'
+ UNMATCHED_SEQUENCE_NAME = 'unmatched_primary_key_default_value_seq'
+ UNMATCHED_PK_TABLE_NAME = 'table_with_unmatched_sequence_for_pk'
class Thing1 < ActiveRecord::Base
self.table_name = "test_schema.things"
@@ -60,6 +62,8 @@ class SchemaTest < ActiveRecord::TestCase
@connection.execute "CREATE INDEX #{INDEX_D_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_D_COLUMN} DESC);"
@connection.execute "CREATE INDEX #{INDEX_D_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_D_COLUMN} DESC);"
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{PK_TABLE_NAME} (id serial primary key)"
+ @connection.execute "CREATE SEQUENCE #{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}"
+ @connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{UNMATCHED_PK_TABLE_NAME} (id integer NOT NULL DEFAULT nextval('#{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}'::regclass), CONSTRAINT unmatched_pkey PRIMARY KEY (id))"
end
def teardown
@@ -241,12 +245,12 @@ class SchemaTest < ActiveRecord::TestCase
def test_pk_and_sequence_for_with_schema_specified
[
%("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}"),
- %(#{SCHEMA_NAME}."#{PK_TABLE_NAME}"),
- %(#{SCHEMA_NAME}.#{PK_TABLE_NAME})
+ %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
].each do |given|
pk, seq = @connection.pk_and_sequence_for(given)
assert_equal 'id', pk, "primary key should be found when table referenced as #{given}"
- assert_equal "#{SCHEMA_NAME}.#{PK_TABLE_NAME}_id_seq", seq, "sequence name should be found when table referenced as #{given}"
+ assert_equal "#{PK_TABLE_NAME}_id_seq", seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}")
+ assert_equal "#{UNMATCHED_SEQUENCE_NAME}", seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
end
end
diff --git a/activeresource/lib/active_resource/version.rb b/activeresource/lib/active_resource/version.rb
index e9561df285..a7c7776a6b 100644
--- a/activeresource/lib/active_resource/version.rb
+++ b/activeresource/lib/active_resource/version.rb
@@ -2,8 +2,8 @@ module ActiveResource
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 1
- PRE = nil
+ TINY = 2
+ PRE = "rc1"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/activesupport/lib/active_support/version.rb b/activesupport/lib/active_support/version.rb
index ef2c69e695..3ba71473c3 100644
--- a/activesupport/lib/active_support/version.rb
+++ b/activesupport/lib/active_support/version.rb
@@ -2,8 +2,8 @@ module ActiveSupport
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 1
- PRE = nil
+ TINY = 2
+ PRE = "rc1"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/activesupport/test/core_ext/range_ext_test.rb b/activesupport/test/core_ext/range_ext_test.rb
index f9fb4f833a..360c97031c 100644
--- a/activesupport/test/core_ext/range_ext_test.rb
+++ b/activesupport/test/core_ext/range_ext_test.rb
@@ -54,7 +54,7 @@ class RangeTest < Test::Unit::TestCase
end
def test_should_include_identical_exclusive_with_floats
- assert (1.0...10.0).include?(1.0...10.0)
+ assert((1.0...10.0).include?(1.0...10.0))
end
def test_blockless_step
diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb
index 048bd6d35b..a5719a84e5 100644
--- a/railties/lib/rails/version.rb
+++ b/railties/lib/rails/version.rb
@@ -2,8 +2,8 @@ module Rails
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 1
- PRE = nil
+ TINY = 2
+ PRE = "rc1"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/version.rb b/version.rb
index 048bd6d35b..a5719a84e5 100644
--- a/version.rb
+++ b/version.rb
@@ -2,8 +2,8 @@ module Rails
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 1
- PRE = nil
+ TINY = 2
+ PRE = "rc1"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end