diff options
17 files changed, 105 insertions, 17 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index ed3135f384..566b6af378 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,11 +1,11 @@ ## Rails 3.2.3 (unreleased) ## -* Remove the leading \n added by textarea on assert_select. *Santiago Pastorino* - * Fix #5632, render :inline set the proper rendered format. *Santiago Pastorino* * Fix textarea rendering when using plugins like HAML. Such plugins encode the first newline character in the content. This issue was introduced in https://github.com/rails/rails/pull/5191 *James Coleman* +* Remove the leading \n added by textarea on assert_select. *Santiago Pastorino* + * Add `config.action_view.embed_authenticity_token_in_remote_forms` (defaults to true) which allows to set if authenticity token will be included by default in remote forms. If you change it to false, you can still force authenticity token by passing `:authenticity_token => true` in form options *Piotr Sarnacki* * Do not include the authenticity token in forms where remote: true as ajax forms use the meta-tag value *DHH* diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index edca950638..252fe1ed03 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -656,15 +656,16 @@ module ActionView # 'Accept <a href="/terms">Terms</a>.'.html_safe # end def label(object_name, method, content_or_options = nil, options = nil, &block) + options ||= {} + content_is_options = content_or_options.is_a?(Hash) if content_is_options || block_given? - options = content_or_options if content_is_options + options.merge!(content_or_options) if content_is_options text = nil else text = content_or_options end - options ||= {} InstanceTag.new(object_name, method, self, options.delete(:object)).to_label_tag(text, options, &block) end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index f9940ead58..7eeede7087 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -943,6 +943,41 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_form_for_label_error_wrapping + form_for(@post) do |f| + concat f.label(:author_name, :class => 'label') + concat f.text_field(:author_name) + concat f.submit('Create post') + end + + expected = whole_form("/posts/123", "edit_post_123" , "edit_post", :method => "put") do + "<div class='field_with_errors'><label for='post_author_name' class='label'>Author name</label></div>" + + "<div class='field_with_errors'><input name='post[author_name]' size='30' type='text' id='post_author_name' value='' /></div>" + + "<input name='commit' type='submit' value='Create post' />" + end + + assert_dom_equal expected, output_buffer + end + + + def test_form_for_label_error_wrapping_without_conventional_instance_variable + post = remove_instance_variable :@post + + form_for(post) do |f| + concat f.label(:author_name, :class => 'label') + concat f.text_field(:author_name) + concat f.submit('Create post') + end + + expected = whole_form("/posts/123", "edit_post_123" , "edit_post", :method => "put") do + "<div class='field_with_errors'><label for='post_author_name' class='label'>Author name</label></div>" + + "<div class='field_with_errors'><input name='post[author_name]' size='30' type='text' id='post_author_name' value='' /></div>" + + "<input name='commit' type='submit' value='Create post' />" + end + + assert_dom_equal expected, output_buffer + end + def test_form_for_with_namespace form_for(@post, :namespace => 'namespace') do |f| concat f.text_field(:title) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 16c525d211..ffd74893be 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,9 @@ +## Rails 3.2.4 (unreleased) ## + +* Association preloading shouldn't be affected by the current scoping. + This could cause infinite recursion and potentially other problems. + See GH #5667. *Jon Leighton* + ## Rails 3.2.3 (unreleased) ## * Added find_or_create_by_{attribute}! dynamic method. *Andrew White* diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb index 779f8164cc..ab50e43ea0 100644 --- a/activerecord/lib/active_record/associations/preloader/association.rb +++ b/activerecord/lib/active_record/associations/preloader/association.rb @@ -77,7 +77,7 @@ module ActiveRecord # Some databases impose a limit on the number of ids in a list (in Oracle it's 1000) # Make several smaller queries if necessary or make one query if the adapter supports it sliced = owner_keys.each_slice(model.connection.in_clause_length || owner_keys.size) - records = sliced.map { |slice| records_for(slice) }.flatten + records = sliced.map { |slice| records_for(slice).to_a }.flatten end # Each record may have multiple owners, and vice-versa @@ -93,7 +93,8 @@ module ActiveRecord end def build_scope - scope = klass.scoped + scope = klass.unscoped + scope.default_scoped = true scope = scope.where(process_conditions(options[:conditions])) scope = scope.where(process_conditions(preload_options[:conditions])) diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 2a7a77777d..06b66b5195 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -64,6 +64,7 @@ module ActiveRecord return if attribute_methods_generated? superclass.define_attribute_methods unless self == base_class super(column_names) + column_names.each { |name| define_external_attribute_method(name) } @attribute_methods_generated = true end end diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index 1548114580..9b3724777a 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -71,22 +71,25 @@ module ActiveRecord generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 def __temp__ - #{internal_attribute_access_code(attr_name, cast_code)} + #{internal_attribute_access_code(attr_name, attribute_cast_code(attr_name))} end alias_method '#{attr_name}', :__temp__ undef_method :__temp__ STR + end + + private + def define_external_attribute_method(attr_name) generated_external_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 def __temp__(v, attributes, attributes_cache, attr_name) - #{external_attribute_access_code(attr_name, cast_code)} + #{external_attribute_access_code(attr_name, attribute_cast_code(attr_name))} end alias_method '#{attr_name}', :__temp__ undef_method :__temp__ STR end - private def cacheable_column?(column) attribute_types_cached_by_default.include?(column.type) end diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb index 17cf34cdf6..c9b2edbd8c 100644 --- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb +++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb @@ -43,6 +43,7 @@ module ActiveRecord end time = time.in_time_zone rescue nil if time write_attribute(:#{attr_name}, original_time) + #{attr_name}_will_change! @attributes_cache["#{attr_name}"] = time end EOV diff --git a/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb b/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb index 9ca63a209e..b9b5ec7956 100644 --- a/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb +++ b/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb @@ -13,9 +13,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration <% attributes.each do |attribute| -%> <%- if migration_action -%> <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><%= attribute.inject_options %><% end %> - <% if attribute.has_index? && migration_action == 'add' %> + <%- if attribute.has_index? && migration_action == 'add' -%> add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %> - <% end -%> + <%- end -%> <%- end -%> <%- end -%> end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 1dc71ac4cc..28bf1c60e5 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -1095,4 +1095,15 @@ class EagerAssociationTest < ActiveRecord::TestCase Post.includes(:comments).order(nil).where(:comments => {:body => "Thank you for the welcome"}).first end end + + test "scoping with a circular preload" do + assert_equal Comment.find(1), Comment.preload(:post => :comments).scoping { Comment.find(1) } + end + + test "preload ignores the scoping" do + assert_equal( + Comment.find(1).post, + Post.where('1 = 0').scoping { Comment.preload(:post).find(1).post } + ) + end end diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb index 6f5644ada0..f4592f7d0e 100644 --- a/activerecord/test/cases/associations/join_model_test.rb +++ b/activerecord/test/cases/associations/join_model_test.rb @@ -403,7 +403,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_has_many_through_polymorphic_has_one - assert_equal Tagging.find(1,2).sort_by { |t| t.id }, authors(:david).tagging.order(:id) + assert_equal Tagging.find(1,2).sort_by { |t| t.id }, authors(:david).tagging.order('taggings.id') end def test_has_many_through_polymorphic_has_many diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index acb9a44305..5e5325b570 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -620,6 +620,20 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end + def test_time_zone_aware_attribute_saved + old_default, ActiveRecord::Base.default_timezone = ActiveRecord::Base.default_timezone, :utc + + in_time_zone 1 do + record = @target.create(:written_on => '2012-02-20 10:00') + + record.written_on = '2012-02-20 09:00' + record.save + assert_equal Time.zone.local(2012, 02, 20, 9), record.reload.written_on + end + ensure + ActiveRecord::Base.default_timezone = old_default + end + def test_setting_time_zone_aware_attribute_to_blank_string_returns_nil in_time_zone "Pacific Time (US & Canada)" do record = @target.new diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index aeb44da2b2..300a3636e3 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -61,7 +61,11 @@ end class Weird < ActiveRecord::Base; end -class Boolean < ActiveRecord::Base; end +class Boolean < ActiveRecord::Base + def has_fun + super + end +end class LintTest < ActiveRecord::TestCase include ActiveModel::Lint::Tests @@ -930,6 +934,16 @@ class BasicsTest < ActiveRecord::TestCase assert b_true.value? end + def test_boolean_without_questionmark + b_true = Boolean.create({ "value" => true }) + true_id = b_true.id + + subclass = Class.new(Boolean).find true_id + superclass = Boolean.find true_id + + assert_equal superclass.read_attribute(:has_fun), subclass.read_attribute(:has_fun) + end + def test_boolean_cast_from_string b_blank = Boolean.create({ "value" => "" }) blank_id = b_blank.id diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index fb4ea4223d..7028b7fd1b 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -90,6 +90,7 @@ ActiveRecord::Schema.define do create_table :booleans, :force => true do |t| t.boolean :value + t.boolean :has_fun, :null => false, :default => false end create_table :bulbs, :force => true do |t| diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index a942c11518..2843ac8c1a 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -139,13 +139,13 @@ module Rails <<-GEMFILE.strip_heredoc gem 'rails', :path => '#{Rails::Generators::RAILS_DEV_PATH}' gem 'journey', :git => 'git://github.com/rails/journey.git' - gem 'arel', :git => 'git://github.com/rails/arel.git' + gem 'arel', :git => 'git://github.com/rails/arel.git', :branch => '3-0-stable' GEMFILE elsif options.edge? <<-GEMFILE.strip_heredoc gem 'rails', :git => 'git://github.com/rails/rails.git', :branch => '3-2-stable' gem 'journey', :git => 'git://github.com/rails/journey.git' - gem 'arel', :git => 'git://github.com/rails/arel.git' + gem 'arel', :git => 'git://github.com/rails/arel.git', :branch => '3-0-stable' GEMFILE else <<-GEMFILE.strip_heredoc diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt index 0f571f7c1a..b7a5af178d 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt @@ -21,7 +21,7 @@ # Generate digests for assets URLs config.assets.digest = true - # Defaults to Rails.root.join("public/assets") + # Defaults to nil and saved in location specified by config.assets.prefix # config.assets.manifest = YOUR_PATH <%- end -%> diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb index b262951b88..c072aaab26 100644 --- a/railties/test/generators/shared_generator_tests.rb +++ b/railties/test/generators/shared_generator_tests.rb @@ -127,7 +127,7 @@ module SharedGeneratorTests quietly { generator.invoke_all } assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["'],\s+:branch\s+=>\s+["']3-2-stable["']$} assert_file 'Gemfile', %r{^gem\s+["']journey["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/journey.git")}["']$} - assert_file 'Gemfile', %r{^gem\s+["']arel["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/arel.git")}["']$} + assert_file 'Gemfile', %r{^gem\s+["']arel["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/arel.git")}["'].*$} end def test_skip_gemfile |