aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG2
-rwxr-xr-xactiverecord/lib/active_record/fixtures.rb35
-rw-r--r--activerecord/test/fixtures/db_definitions/schema.rb2
-rw-r--r--activerecord/test/fixtures/parrot.rb1
-rw-r--r--activerecord/test/fixtures/pirate.rb1
-rw-r--r--activerecord/test/fixtures/treasure.rb1
-rw-r--r--activerecord/test/fixtures/treasures.yml2
-rwxr-xr-xactiverecord/test/fixtures_test.rb5
8 files changed, 49 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 7a9b1e11af..b0789b4694 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Add 'foxy' support for fixtures of polymorphic associations. #10183 [jbarnette, David Lowenfels]
+
* attr_readonly behaves well with optimistic locking. #10188 [Nick Bugajski]
* Base#to_xml supports the nil="true" attribute like Hash#to_xml. #8268 [Catfish]
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 84e7c84d64..97fca6026b 100755
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -301,6 +301,31 @@ end
# a target *label* for the *association* (monkey: george) rather than
# a target *id* for the *FK* (monkey_id: 1).
#
+# ==== Polymorphic belongs_to
+#
+# Supporting polymorphic relationships is a little bit more complicated, since
+# ActiveRecord needs to know what type your association is pointing at. Something
+# like this should look familiar:
+#
+# ### in fruit.rb
+#
+# belongs_to :eater, :polymorphic => true
+#
+# ### in fruits.yml
+#
+# apple:
+# id: 1
+# name: apple
+# eater_id: 1
+# eater_type: Monkey
+#
+# Can we do better? You bet!
+#
+# apple:
+# eater: george (Monkey)
+#
+# Just provide the polymorphic target type and ActiveRecord will take care of the rest.
+#
# === has_and_belongs_to_many
#
# Time to give our monkey some fruit.
@@ -556,6 +581,16 @@ class Fixtures < YAML::Omap
case association.macro
when :belongs_to
if value = row.delete(association.name.to_s)
+ if association.options[:polymorphic]
+ if value.sub!(/\s*\(([^\)]*)\)\s*$/, "")
+ target_type = $1
+ target_type_name = (association.options[:foreign_type] || "#{association.name}_type").to_s
+
+ # support polymorphic belongs_to as "label (Type)"
+ row[target_type_name] = target_type
+ end
+ end
+
fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s
row[fk_name] = Fixtures.identify(value)
end
diff --git a/activerecord/test/fixtures/db_definitions/schema.rb b/activerecord/test/fixtures/db_definitions/schema.rb
index 5bde5126d5..12dbcb8423 100644
--- a/activerecord/test/fixtures/db_definitions/schema.rb
+++ b/activerecord/test/fixtures/db_definitions/schema.rb
@@ -327,6 +327,8 @@ ActiveRecord::Schema.define do
create_table :treasures, :force => true do |t|
t.column :name, :string
+ t.column :looter_id, :integer
+ t.column :looter_type, :string
end
create_table :parrots_treasures, :id => false, :force => true do |t|
diff --git a/activerecord/test/fixtures/parrot.rb b/activerecord/test/fixtures/parrot.rb
index 340c73b907..10850669e7 100644
--- a/activerecord/test/fixtures/parrot.rb
+++ b/activerecord/test/fixtures/parrot.rb
@@ -1,4 +1,5 @@
class Parrot < ActiveRecord::Base
has_and_belongs_to_many :pirates
has_and_belongs_to_many :treasures
+ has_many :loots, :as => :looter
end
diff --git a/activerecord/test/fixtures/pirate.rb b/activerecord/test/fixtures/pirate.rb
index d22d66bac9..f7193dfbe0 100644
--- a/activerecord/test/fixtures/pirate.rb
+++ b/activerecord/test/fixtures/pirate.rb
@@ -1,4 +1,5 @@
class Pirate < ActiveRecord::Base
belongs_to :parrot
has_and_belongs_to_many :parrots
+ has_many :loots, :as => :looter
end
diff --git a/activerecord/test/fixtures/treasure.rb b/activerecord/test/fixtures/treasure.rb
index cbb3ec3c08..7a429e2a2f 100644
--- a/activerecord/test/fixtures/treasure.rb
+++ b/activerecord/test/fixtures/treasure.rb
@@ -1,3 +1,4 @@
class Treasure < ActiveRecord::Base
has_and_belongs_to_many :parrots
+ belongs_to :looter, :polymorphic => true
end
diff --git a/activerecord/test/fixtures/treasures.yml b/activerecord/test/fixtures/treasures.yml
index c6fe30d0e3..9db15798fd 100644
--- a/activerecord/test/fixtures/treasures.yml
+++ b/activerecord/test/fixtures/treasures.yml
@@ -3,6 +3,8 @@ diamond:
sapphire:
name: $LABEL
+ looter: redbeard (Pirate)
ruby:
name: $LABEL
+ looter: louis (Parrot)
diff --git a/activerecord/test/fixtures_test.rb b/activerecord/test/fixtures_test.rb
index 40790a607d..6f11a337b1 100755
--- a/activerecord/test/fixtures_test.rb
+++ b/activerecord/test/fixtures_test.rb
@@ -528,6 +528,11 @@ class FoxyFixturesTest < Test::Unit::TestCase
def test_supports_label_interpolation
assert_equal("frederick", parrots(:frederick).name)
end
+
+ def test_supports_polymorphic_belongs_to
+ assert_equal(pirates(:redbeard), treasures(:sapphire).looter)
+ assert_equal(parrots(:louis), treasures(:ruby).looter)
+ end
end
class ActiveSupportSubclassWithFixturesTest < ActiveSupport::TestCase