aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb7
-rw-r--r--actionpack/test/controller/test_test.rb5
-rw-r--r--actionpack/test/template/form_helper_test.rb11
-rw-r--r--activemodel/lib/active_model/errors.rb4
-rw-r--r--activemodel/test/cases/serializeration/json_serialization_test.rb16
-rw-r--r--activemodel/test/cases/validations_test.rb8
-rw-r--r--activerecord/lib/active_record/associations.rb19
-rw-r--r--activerecord/lib/active_record/callbacks.rb8
-rw-r--r--activerecord/lib/active_record/persistence.rb13
-rw-r--r--activerecord/lib/active_record/reflection.rb26
-rw-r--r--activerecord/lib/active_record/timestamp.rb13
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb40
-rw-r--r--activerecord/test/cases/associations_test.rb13
-rw-r--r--activerecord/test/cases/timestamp_test.rb19
-rw-r--r--activerecord/test/fixtures/subscriptions.yml2
-rw-r--r--activerecord/test/models/book.rb3
-rw-r--r--activerecord/test/models/electron.rb3
-rw-r--r--activerecord/test/models/liquid.rb5
-rw-r--r--activerecord/test/models/molecule.rb4
-rw-r--r--activerecord/test/schema/schema.rb15
-rw-r--r--activeresource/lib/active_resource/base.rb6
-rw-r--r--activeresource/test/cases/base/load_test.rb12
-rw-r--r--activesupport/lib/active_support/core_ext/object.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/object/returning.rb43
-rw-r--r--activesupport/lib/active_support/hash_with_indifferent_access.rb1
-rw-r--r--railties/lib/rails/generators/actions.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb7
-rw-r--r--railties/lib/rails/test_unit/testing.rake2
-rw-r--r--railties/test/generators/app_generator_test.rb24
-rw-r--r--railties/test/generators/scaffold_generator_test.rb15
30 files changed, 291 insertions, 56 deletions
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index f8e60faa2a..ebe055bebd 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -215,7 +215,7 @@ module ActionView
# ...
# <% end %>
#
- # If your resource has associations defined, for example, you want to add comments
+ # If your resource has associations defined, for example, you want to add comments
# to the post given that the routes are set correctly:
#
# <%= form_for([@document, @comment]) do |f| %>
@@ -583,8 +583,9 @@ module ActionView
# 'Accept <a href="/terms">Terms</a>.'
# end
def label(object_name, method, content_or_options = nil, options = nil, &block)
- if block_given?
- options = content_or_options if content_or_options.is_a?(Hash)
+ content_is_options = content_or_options.is_a?(Hash)
+ if content_is_options || block_given?
+ options = content_or_options if content_is_options
text = nil
else
text = content_or_options
diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb
index 950ad9266f..13c9d9ee38 100644
--- a/actionpack/test/controller/test_test.rb
+++ b/actionpack/test/controller/test_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require 'controller/fake_controllers'
+require 'active_support/ordered_hash'
class TestTest < ActionController::TestCase
class TestController < ActionController::Base
@@ -137,14 +138,14 @@ XML
end
def test_raw_post_handling
- params = {:page => {:name => 'page name'}, 'some key' => 123}
+ params = ActiveSupport::OrderedHash[:page, {:name => 'page name'}, 'some key', 123]
post :render_raw_post, params.dup
assert_equal params.to_query, @response.body
end
def test_body_stream
- params = { :page => { :name => 'page name' }, 'some key' => 123 }
+ params = ActiveSupport::OrderedHash[:page, { :name => 'page name' }, 'some key', 123]
post :render_body, params.dup
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index f248a38ae9..9086a23345 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -120,6 +120,13 @@ class FormHelperTest < ActionView::TestCase
I18n.locale = old_locale
end
+ def test_label_with_locales_and_options
+ old_locale, I18n.locale = I18n.locale, :label
+ assert_dom_equal('<label for="post_body" class="post_body">Write entire text here</label>', label(:post, :body, :class => 'post_body'))
+ ensure
+ I18n.locale = old_locale
+ end
+
def test_label_with_for_attribute_as_symbol
assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, :for => "my_for"))
end
@@ -620,7 +627,7 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_symbol_object_name
form_for(@post, :as => "other_name", :html => { :id => 'create-post' }) do |f|
- concat f.label(:title)
+ concat f.label(:title, :class => 'post_title')
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
@@ -628,7 +635,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/posts/123", "create-post", "other_name_edit", :method => "put") do
- "<label for='other_name_title'>Title</label>" +
+ "<label for='other_name_title' class='post_title'>Title</label>" +
"<input name='other_name[title]' size='30' id='other_name_title' value='Hello World' type='text' />" +
"<textarea name='other_name[body]' id='other_name_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='other_name[secret]' value='0' type='hidden' />" +
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index bf93126d27..f39678db83 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -169,9 +169,9 @@ module ActiveModel
to_a.to_xml options.reverse_merge(:root => "errors", :skip_types => true)
end
- # Returns an array as JSON representation for this object.
+ # Returns an ActiveSupport::OrderedHash that can be used as the JSON representation for this object.
def as_json(options=nil)
- to_a
+ self
end
# Adds +message+ to the error messages on +attribute+, which will be returned on a call to
diff --git a/activemodel/test/cases/serializeration/json_serialization_test.rb b/activemodel/test/cases/serializeration/json_serialization_test.rb
index 04b50e5bb8..1ac991a8f1 100644
--- a/activemodel/test/cases/serializeration/json_serialization_test.rb
+++ b/activemodel/test/cases/serializeration/json_serialization_test.rb
@@ -89,7 +89,7 @@ class JsonSerializationTest < ActiveModel::TestCase
assert_match %r{"preferences":\{"shows":"anime"\}}, json
end
- test "methds are called on object" do
+ test "methods are called on object" do
# Define methods on fixture.
def @contact.label; "Has cheezburger"; end
def @contact.favorite_quote; "Constraints are liberating"; end
@@ -102,4 +102,18 @@ class JsonSerializationTest < ActiveModel::TestCase
assert_match %r{"label":"Has cheezburger"}, methods_json
assert_match %r{"favorite_quote":"Constraints are liberating"}, methods_json
end
+
+ test "should return OrderedHash for errors" do
+ car = Automobile.new
+
+ # run the validation
+ car.valid?
+
+ hash = ActiveSupport::OrderedHash.new
+ hash[:make] = "can't be blank"
+ hash[:model] = "is too short (minimum is 2 characters)"
+ assert_equal hash.to_json, car.errors.to_json
+ end
+
+
end
diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb
index e94d8ce88c..8d6bdeb6a5 100644
--- a/activemodel/test/cases/validations_test.rb
+++ b/activemodel/test/cases/validations_test.rb
@@ -170,9 +170,11 @@ class ValidationsTest < ActiveModel::TestCase
assert_match %r{<errors>}, xml
assert_match %r{<error>Title can't be blank</error>}, xml
assert_match %r{<error>Content can't be blank</error>}, xml
-
- json = t.errors.to_json
- assert_equal t.errors.to_a.to_json, json
+
+ hash = ActiveSupport::OrderedHash.new
+ hash[:title] = "can't be blank"
+ hash[:content] = "can't be blank"
+ assert_equal t.errors.to_json, hash.to_json
end
def test_validation_order
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index f540aa7f25..fdc203e298 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1437,9 +1437,11 @@ module ActiveRecord
association.replace(new_value)
association
end
-
+
redefine_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
- ids = (new_value || []).reject { |nid| nid.blank? }.map(&:to_i)
+ pk_column = reflection.primary_key_column
+ ids = (new_value || []).reject { |nid| nid.blank? }
+ ids.map!{ |i| pk_column.type_cast(i) }
send("#{reflection.name}=", reflection.klass.find(ids).index_by(&:id).values_at(*ids))
end
end
@@ -1498,6 +1500,7 @@ module ActiveRecord
end
end
after_save(method_name)
+ after_touch(method_name)
after_destroy(method_name)
end
@@ -1802,9 +1805,7 @@ module ActiveRecord
case associations
when Symbol, String
reflection = base.reflections[associations]
- if reflection && reflection.collection?
- records.each { |record| record.send(reflection.name).target.uniq! }
- end
+ remove_uniq_by_reflection(reflection, records)
when Array
associations.each do |association|
remove_duplicate_results!(base, records, association)
@@ -1812,6 +1813,7 @@ module ActiveRecord
when Hash
associations.keys.each do |name|
reflection = base.reflections[name]
+ remove_uniq_by_reflection(reflection, records)
parent_records = []
records.each do |record|
@@ -1830,6 +1832,7 @@ module ActiveRecord
end
protected
+
def build(associations, parent = nil, join_class = Arel::InnerJoin)
parent ||= @joins.last
case associations
@@ -1852,6 +1855,12 @@ module ActiveRecord
end
end
+ def remove_uniq_by_reflection(reflection, records)
+ if reflection && reflection.collection?
+ records.each { |record| record.send(reflection.name).target.uniq! }
+ end
+ end
+
def build_join_association(reflection, parent)
JoinAssociation.new(reflection, self, parent)
end
diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb
index 637dac450b..82c45a41b0 100644
--- a/activerecord/lib/active_record/callbacks.rb
+++ b/activerecord/lib/active_record/callbacks.rb
@@ -228,7 +228,7 @@ module ActiveRecord
extend ActiveSupport::Concern
CALLBACKS = [
- :after_initialize, :after_find, :before_validation, :after_validation,
+ :after_initialize, :after_find, :after_touch, :before_validation, :after_validation,
:before_save, :around_save, :after_save, :before_create, :around_create,
:after_create, :before_update, :around_update, :after_update,
:before_destroy, :around_destroy, :after_destroy
@@ -238,7 +238,7 @@ module ActiveRecord
extend ActiveModel::Callbacks
include ActiveModel::Validations::Callbacks
- define_model_callbacks :initialize, :find, :only => :after
+ define_model_callbacks :initialize, :find, :touch, :only => :after
define_model_callbacks :save, :create, :update, :destroy
end
@@ -256,6 +256,10 @@ module ActiveRecord
_run_destroy_callbacks { super }
end
+ def touch(*) #:nodoc:
+ _run_touch_callbacks { super }
+ end
+
def deprecated_callback_method(symbol) #:nodoc:
if respond_to?(symbol, true)
ActiveSupport::Deprecation.warn("Overwriting #{symbol} in your models has been deprecated, please use Base##{symbol} :method_name instead")
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 38b91652ee..cbc2220e96 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -218,6 +218,19 @@ module ActiveRecord
self
end
+ # Saves the record with the updated_at/on attributes set to the current time.
+ # Please note that no validation is performed and no callbacks are executed.
+ # If an attribute name is passed, that attribute is updated along with
+ # updated_at/on attributes.
+ #
+ # Examples:
+ #
+ # product.touch # updates updated_at/on
+ # product.touch(:designed_at) # updates the designed_at attribute and updated_at/on
+ def touch(attribute = nil)
+ update_attribute(attribute, current_time_from_proper_timezone)
+ end
+
private
def create_or_update
raise ReadOnlyRecord if readonly?
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 03a932f642..7f47a812eb 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -91,25 +91,19 @@ module ActiveRecord
#
# <tt>composed_of :balance, :class_name => 'Money'</tt> returns <tt>:balance</tt>
# <tt>has_many :clients</tt> returns <tt>:clients</tt>
- def name
- @name
- end
+ attr_reader :name
# Returns the macro type.
#
# <tt>composed_of :balance, :class_name => 'Money'</tt> returns <tt>:composed_of</tt>
# <tt>has_many :clients</tt> returns <tt>:has_many</tt>
- def macro
- @macro
- end
+ attr_reader :macro
# Returns the hash of options used for the macro.
#
# <tt>composed_of :balance, :class_name => 'Money'</tt> returns <tt>{ :class_name => "Money" }</tt>
# <tt>has_many :clients</tt> returns +{}+
- def options
- @options
- end
+ attr_reader :options
# Returns the class for the macro.
#
@@ -137,11 +131,6 @@ module ActiveRecord
@sanitized_conditions ||= klass.send(:sanitize_sql, options[:conditions]) if options[:conditions]
end
- # Returns +true+ if +self+ is a +belongs_to+ reflection.
- def belongs_to?
- macro == :belongs_to
- end
-
private
def derive_class_name
name.to_s.camelize
@@ -213,6 +202,10 @@ module ActiveRecord
@primary_key_name ||= options[:foreign_key] || derive_primary_key_name
end
+ def primary_key_column
+ @primary_key_column ||= klass.columns.find { |c| c.name == klass.primary_key }
+ end
+
def association_foreign_key
@association_foreign_key ||= @options[:association_foreign_key] || class_name.foreign_key
end
@@ -307,6 +300,11 @@ module ActiveRecord
dependent_conditions
end
+ # Returns +true+ if +self+ is a +belongs_to+ reflection.
+ def belongs_to?
+ macro == :belongs_to
+ end
+
private
def derive_class_name
class_name = name.to_s.camelize
diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb
index 92f7a7753d..32b3f03f13 100644
--- a/activerecord/lib/active_record/timestamp.rb
+++ b/activerecord/lib/active_record/timestamp.rb
@@ -31,19 +31,6 @@ module ActiveRecord
class_inheritable_accessor :record_timestamps, :instance_writer => false
self.record_timestamps = true
end
-
- # Saves the record with the updated_at/on attributes set to the current time.
- # Please note that no validation is performed and no callbacks are executed.
- # If an attribute name is passed, that attribute is updated along with
- # updated_at/on attributes.
- #
- # Examples:
- #
- # product.touch # updates updated_at/on
- # product.touch(:designed_at) # updates the designed_at attribute and updated_at/on
- def touch(attribute = nil)
- update_attribute(attribute, current_time_from_proper_timezone)
- end
private
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index e4dd810732..0eaadac5ae 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -14,9 +14,14 @@ require 'models/toy'
require 'models/contract'
require 'models/company'
require 'models/developer'
+require 'models/subscriber'
+require 'models/book'
+require 'models/subscription'
class HasManyThroughAssociationsTest < ActiveRecord::TestCase
- fixtures :posts, :readers, :people, :comments, :authors, :owners, :pets, :toys, :jobs, :references, :companies
+ fixtures :posts, :readers, :people, :comments, :authors,
+ :owners, :pets, :toys, :jobs, :references, :companies,
+ :subscribers, :books, :subscriptions, :developers
# Dummies to force column loads so query counts are clean.
def setup
@@ -383,4 +388,37 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
lambda { authors(:david).very_special_comments.delete(authors(:david).very_special_comments.first) },
].each {|block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) }
end
+
+ def test_collection_singular_ids_getter_with_string_primary_keys
+ book = books(:awdr)
+ assert_equal 2, book.subscriber_ids.size
+ assert_equal [subscribers(:first).nick, subscribers(:second).nick].sort, book.subscriber_ids.sort
+ end
+
+ def test_collection_singular_ids_setter
+ company = companies(:rails_core)
+ dev = Developer.find(:first)
+
+ company.developer_ids = [dev.id]
+ assert_equal [dev], company.developers
+ end
+
+ def test_collection_singular_ids_setter_with_string_primary_keys
+ assert_nothing_raised do
+ book = books(:awdr)
+ book.subscriber_ids = [subscribers(:second).nick]
+ assert_equal [subscribers(:second)], book.subscribers(true)
+
+ book.subscriber_ids = []
+ assert_equal [], book.subscribers(true)
+ end
+
+ end
+
+ def test_collection_singular_ids_setter_raises_exception_when_invalid_ids_set
+ company = companies(:rails_core)
+ ids = [Developer.find(:first).id, -9999]
+ assert_raises(ActiveRecord::RecordNotFound) {company.developer_ids= ids}
+ end
+
end
diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb
index a1c794c084..d328ca630b 100644
--- a/activerecord/test/cases/associations_test.rb
+++ b/activerecord/test/cases/associations_test.rb
@@ -14,11 +14,24 @@ require 'models/reader'
require 'models/parrot'
require 'models/ship_part'
require 'models/ship'
+require 'models/liquid'
+require 'models/molecule'
+require 'models/electron'
class AssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :developers_projects,
:computers, :people, :readers
+ def test_eager_loading_should_not_change_count_of_children
+ liquid = Liquid.create(:name => 'salty')
+ molecule = liquid.molecules.create(:name => 'molecule_1')
+ molecule.electrons.create(:name => 'electron_1')
+ molecule.electrons.create(:name => 'electron_2')
+
+ liquids = Liquid.includes(:molecules => :electrons).where('molecules.id is not null')
+ assert_equal 1, liquids[0].molecules.length
+ end
+
def test_loading_the_association_target_should_keep_child_records_marked_for_destruction
ship = Ship.create!(:name => "The good ship Dollypop")
part = ship.parts.create!(:name => "Mast")
diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb
index f765540808..06ab7aa9c7 100644
--- a/activerecord/test/cases/timestamp_test.rb
+++ b/activerecord/test/cases/timestamp_test.rb
@@ -2,9 +2,10 @@ require 'cases/helper'
require 'models/developer'
require 'models/owner'
require 'models/pet'
+require 'models/toy'
class TimestampTest < ActiveRecord::TestCase
- fixtures :developers, :owners, :pets
+ fixtures :developers, :owners, :pets, :toys
def setup
@developer = Developer.first
@@ -82,4 +83,20 @@ class TimestampTest < ActiveRecord::TestCase
ensure
Pet.belongs_to :owner, :touch => true
end
+
+ def test_touching_a_record_touches_parent_record_and_grandparent_record
+ Toy.belongs_to :pet, :touch => true
+ Pet.belongs_to :owner, :touch => true
+
+ toy = Toy.first
+ pet = toy.pet
+ owner = pet.owner
+
+ owner.update_attribute(:updated_at, (time = 3.days.ago))
+ toy.touch
+
+ assert_not_equal time, owner.updated_at
+ ensure
+ Toy.belongs_to :pet
+ end
end
diff --git a/activerecord/test/fixtures/subscriptions.yml b/activerecord/test/fixtures/subscriptions.yml
index 371bfd3422..5a93c12193 100644
--- a/activerecord/test/fixtures/subscriptions.yml
+++ b/activerecord/test/fixtures/subscriptions.yml
@@ -9,4 +9,4 @@ webster_rfr:
alterself_awdr:
id: 3
subscriber_id: alterself
- book_id: 3 \ No newline at end of file
+ book_id: 1
diff --git a/activerecord/test/models/book.rb b/activerecord/test/models/book.rb
index cfd07abddc..1e030b4f59 100644
--- a/activerecord/test/models/book.rb
+++ b/activerecord/test/models/book.rb
@@ -1,4 +1,7 @@
class Book < ActiveRecord::Base
has_many :citations, :foreign_key => 'book1_id'
has_many :references, :through => :citations, :source => :reference_of, :uniq => true
+
+ has_many :subscriptions
+ has_many :subscribers, :through => :subscriptions
end
diff --git a/activerecord/test/models/electron.rb b/activerecord/test/models/electron.rb
new file mode 100644
index 0000000000..35af9f679b
--- /dev/null
+++ b/activerecord/test/models/electron.rb
@@ -0,0 +1,3 @@
+class Electron < ActiveRecord::Base
+ belongs_to :molecule
+end
diff --git a/activerecord/test/models/liquid.rb b/activerecord/test/models/liquid.rb
new file mode 100644
index 0000000000..b96c054f6c
--- /dev/null
+++ b/activerecord/test/models/liquid.rb
@@ -0,0 +1,5 @@
+class Liquid < ActiveRecord::Base
+ set_table_name :liquid
+ has_many :molecules, :uniq => true
+end
+
diff --git a/activerecord/test/models/molecule.rb b/activerecord/test/models/molecule.rb
new file mode 100644
index 0000000000..69325b8d29
--- /dev/null
+++ b/activerecord/test/models/molecule.rb
@@ -0,0 +1,4 @@
+class Molecule < ActiveRecord::Base
+ belongs_to :liquid
+ has_many :electrons
+end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index f3fd37cd61..fc3810f82b 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -398,6 +398,7 @@ ActiveRecord::Schema.define do
create_table :pets, :primary_key => :pet_id ,:force => true do |t|
t.string :name
t.integer :owner_id, :integer
+ t.timestamps
end
create_table :pirates, :force => true do |t|
@@ -530,6 +531,7 @@ ActiveRecord::Schema.define do
create_table :toys, :primary_key => :toy_id ,:force => true do |t|
t.string :name
t.integer :pet_id, :integer
+ t.timestamps
end
create_table :traffic_lights, :force => true do |t|
@@ -616,6 +618,19 @@ ActiveRecord::Schema.define do
t.datetime :updated_at
end
+ create_table :liquid, :force => true do |t|
+ t.string :name
+ end
+ create_table :molecules, :force => true do |t|
+ t.integer :liquid_id
+ t.string :name
+ end
+ create_table :electrons, :force => true do |t|
+ t.integer :molecule_id
+ t.string :name
+ end
+
+
except 'SQLite' do
# fk_test_has_fk should be before fk_test_has_pk
create_table :fk_test_has_fk, :force => true do |t|
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index 72ad2f5872..62420725ad 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -1222,10 +1222,10 @@ module ActiveResource
when Array
resource = find_or_create_resource_for_collection(key)
value.map do |attrs|
- if attrs.is_a?(String) || attrs.is_a?(Numeric)
- attrs.duplicable? ? attrs.dup : attrs
- else
+ if attrs.is_a?(Hash)
resource.new(attrs)
+ else
+ attrs.duplicable? ? attrs.dup : attrs
end
end
when Hash
diff --git a/activeresource/test/cases/base/load_test.rb b/activeresource/test/cases/base/load_test.rb
index 7745a9439b..228dc36d9b 100644
--- a/activeresource/test/cases/base/load_test.rb
+++ b/activeresource/test/cases/base/load_test.rb
@@ -47,6 +47,8 @@ class BaseLoadTest < Test::Unit::TestCase
{ :id => 1, :name => 'Willamette' },
{ :id => 2, :name => 'Columbia', :rafted_by => @matz }],
:postal_codes => [ 97018, 1234567890 ],
+ :dates => [ Time.now ],
+ :votes => [ true, false, true ],
:places => [ "Columbia City", "Unknown" ]}}}
@person = Person.new
@@ -149,6 +151,16 @@ class BaseLoadTest < Test::Unit::TestCase
assert_kind_of Array, places
assert_kind_of String, places.first
assert_equal @deep[:street][:state][:places].first, places.first
+
+ dates = state.dates
+ assert_kind_of Array, dates
+ assert_kind_of Time, dates.first
+ assert_equal @deep[:street][:state][:dates].first, dates.first
+
+ votes = state.votes
+ assert_kind_of Array, votes
+ assert_kind_of TrueClass, votes.first
+ assert_equal @deep[:street][:state][:votes].first, votes.first
end
def test_nested_collections_within_the_same_namespace
diff --git a/activesupport/lib/active_support/core_ext/object.rb b/activesupport/lib/active_support/core_ext/object.rb
index 790a26f5c1..d671da6711 100644
--- a/activesupport/lib/active_support/core_ext/object.rb
+++ b/activesupport/lib/active_support/core_ext/object.rb
@@ -2,6 +2,7 @@ require 'active_support/core_ext/object/acts_like'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/duplicable'
require 'active_support/core_ext/object/try'
+require 'active_support/core_ext/object/returning'
require 'active_support/core_ext/object/conversions'
require 'active_support/core_ext/object/instance_variables'
diff --git a/activesupport/lib/active_support/core_ext/object/returning.rb b/activesupport/lib/active_support/core_ext/object/returning.rb
new file mode 100644
index 0000000000..07250b2a27
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/object/returning.rb
@@ -0,0 +1,43 @@
+class Object
+ # Returns +value+ after yielding +value+ to the block. This simplifies the
+ # process of constructing an object, performing work on the object, and then
+ # returning the object from a method. It is a Ruby-ized realization of the K
+ # combinator, courtesy of Mikael Brockman.
+ #
+ # ==== Examples
+ #
+ # # Without returning
+ # def foo
+ # values = []
+ # values << "bar"
+ # values << "baz"
+ # return values
+ # end
+ #
+ # foo # => ['bar', 'baz']
+ #
+ # # returning with a local variable
+ # def foo
+ # returning values = [] do
+ # values << 'bar'
+ # values << 'baz'
+ # end
+ # end
+ #
+ # foo # => ['bar', 'baz']
+ #
+ # # returning with a block argument
+ # def foo
+ # returning [] do |values|
+ # values << 'bar'
+ # values << 'baz'
+ # end
+ # end
+ #
+ # foo # => ['bar', 'baz']
+ def returning(value)
+ ActiveSupport::Deprecation.warn('Object#returning has been deprecated in favor of Object#tap.', caller)
+ yield(value)
+ value
+ end
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb
index f64f0f44cc..eec5d4cf47 100644
--- a/activesupport/lib/active_support/hash_with_indifferent_access.rb
+++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/hash/keys'
# This class has dubious semantics and we only have it so that
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index 2280cc1507..668ef48892 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -275,7 +275,7 @@ module Rails
#
def route(routing_code)
log :route, routing_code
- sentinel = /\.routes\.draw do(\s*\|map\|)?\s*$/
+ sentinel = /\.routes\.draw do(?:\s*\|map\|)?\s*$/
in_root do
inject_into_file 'config/routes.rb', "\n #{routing_code}\n", { :after => sentinel, :verbose => false }
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 96c49a81bb..a90f109844 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -356,8 +356,13 @@ module Rails
@app_name ||= File.basename(destination_root)
end
+ def defined_app_const_base
+ Rails.respond_to?(:application) && defined?(Rails::Application) &&
+ Rails.application.is_a?(Rails::Application) && Rails.application.class.name.sub(/::Application$/, "")
+ end
+
def app_const_base
- @app_const_base ||= app_name.gsub(/\W/, '_').squeeze('_').camelize
+ @app_const_base ||= defined_app_const_base || app_name.gsub(/\W/, '_').squeeze('_').camelize
end
def app_const
diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake
index ecd513c2c8..38c14fcd6b 100644
--- a/railties/lib/rails/test_unit/testing.rake
+++ b/railties/lib/rails/test_unit/testing.rake
@@ -70,7 +70,7 @@ module Kernel
end
end
-desc 'Runs test:unit, test:functional, test:integration together (also available: test:benchmark, test:profile, test:plugins)'
+desc 'Runs test:units, test:functionals, test:integration together (also available: test:benchmark, test:profile, test:plugins)'
task :test do
errors = %w(test:units test:functionals test:integration).collect do |task|
begin
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 1e0b3bf4c7..21725a380c 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -106,6 +106,30 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file "things-43/config/application.rb", /^module Things43$/
end
+ def test_application_name_is_detected_if_it_exists_and_app_folder_renamed
+ app_root = File.join(destination_root, "myapp")
+ app_moved_root = File.join(destination_root, "myapp_moved")
+
+ run_generator [app_root]
+
+ Rails.application.config.root = app_moved_root
+ Rails.application.class.stubs(:name).returns("Myapp")
+ Rails.application.stubs(:instance_of?).returns(Rails::Application)
+
+ FileUtils.mv(app_root, app_moved_root)
+
+ # forces the shell to automatically overwrite all files
+ Thor::Base.shell.send(:attr_accessor, :always_force)
+ shell = Thor::Base.shell.new
+ shell.send(:always_force=, true)
+
+ generator = Rails::Generators::AppGenerator.new ["rails"], { :with_dispatchers => true },
+ :destination_root => app_moved_root, :shell => shell
+ generator.send(:app_const)
+ silence(:stdout){ generator.send(:create_config_files) }
+ assert_file "myapp_moved/config/environment.rb", /Myapp::Application\.initialize!/
+ end
+
def test_application_names_are_not_singularized
run_generator [File.join(destination_root, "hats")]
assert_file "hats/config/environment.rb", /Hats::Application\.initialize!/
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index ea469cb3c8..f12445ae35 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -216,4 +216,19 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Stylesheets (should not be removed)
assert_file "public/stylesheets/scaffold.css"
end
+
+ def test_scaffold_generator_on_revoke_does_not_mutilate_legacy_map_parameter
+ run_generator
+
+ # Add a |map| parameter to the routes block manually
+ route_path = File.expand_path("config/routes.rb", destination_root)
+ content = File.read(route_path).gsub(/\.routes\.draw do/) do |match|
+ "#{match} |map|"
+ end
+ File.open(route_path, "wb") { |file| file.write(content) }
+
+ run_generator ["product_line"], :behavior => :revoke
+
+ assert_file "config/routes.rb", /\.routes\.draw do\s*\|map\|\s*$/
+ end
end