Skip to content

Instantly share code, notes, and snippets.

@stefanpenner
Created September 1, 2009 20:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stefanpenner/a0401857b8291ea46774 to your computer and use it in GitHub Desktop.
Save stefanpenner/a0401857b8291ea46774 to your computer and use it in GitHub Desktop.
From 3a4497f6fb8b16d7b2c1a3bc02d91d3494e81383 Mon Sep 17 00:00:00 2001
From: Stefan Penner <stefan.penner@gmail.com>
Date: Tue, 1 Sep 2009 15:16:57 -0500
Subject: [PATCH 1/2] added failing spec
---
activerecord/test/cases/base_test.rb | 13 +++++++++++++
activerecord/test/models/author.rb | 3 +++
activerecord/test/models/event.rb | 2 +-
activerecord/test/models/event_author.rb | 4 ++++
activerecord/test/schema/schema.rb | 6 ++++++
5 files changed, 27 insertions(+), 1 deletions(-)
create mode 100644 activerecord/test/models/event_author.rb
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 4530eec..af4757b 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -17,6 +17,7 @@ require 'models/comment'
require 'models/minimalistic'
require 'models/warehouse_thing'
require 'models/parrot'
+require 'models/event_author'
require 'rexml/document'
class Category < ActiveRecord::Base; end
@@ -1003,6 +1004,18 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal "changed", post.body
end
+ def test_multiparameter_attribute_assignment_via_association_proxy
+ multiparameter_date_attribute = {
+ "ends_on(1i)" => "2004", "ends_on(2i)" => "6", "ends_on(3i)" => "24",
+ "ends_on(4i)" => "16", "ends_on(5i)" => "24", "ends_on(6i)" => "00"
+ }
+
+ author = Author.create(:name => "dhh")
+ event = author.events.create(multiparameter_date_attribute)
+
+ assert_equal Time.local(2004,6,24,16,24,0),event.ends_on
+ end
+
def test_multiparameter_attributes_on_date
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "24" }
topic = Topic.find(1)
diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb
index f264f98..9435bb3 100644
--- a/activerecord/test/models/author.rb
+++ b/activerecord/test/models/author.rb
@@ -93,6 +93,9 @@ class Author < ActiveRecord::Base
belongs_to :author_address, :dependent => :destroy
belongs_to :author_address_extra, :dependent => :delete, :class_name => "AuthorAddress"
+ has_many :event_authors
+ has_many :events, :through => :event_authors
+
attr_accessor :post_log
def after_initialize
diff --git a/activerecord/test/models/event.rb b/activerecord/test/models/event.rb
index 99fa0fe..365ab32 100644
--- a/activerecord/test/models/event.rb
+++ b/activerecord/test/models/event.rb
@@ -1,3 +1,3 @@
class Event < ActiveRecord::Base
validates_uniqueness_of :title
-end
\ No newline at end of file
+end
diff --git a/activerecord/test/models/event_author.rb b/activerecord/test/models/event_author.rb
new file mode 100644
index 0000000..26661e1
--- /dev/null
+++ b/activerecord/test/models/event_author.rb
@@ -0,0 +1,4 @@
+class EventAuthor < ActiveRecord::Base
+ belongs_to :author
+ belongs_to :event
+end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index da71aac..0df19c8 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -173,6 +173,12 @@ ActiveRecord::Schema.define do
create_table :events, :force => true do |t|
t.string :title, :limit => 5
+ t.datetime :ends_on
+ end
+
+ create_table :event_authors, :force => true do |t|
+ t.integer :event_id
+ t.integer :author_id
end
create_table :funny_jokes, :force => true do |t|
--
1.6.4
From 1d4dbc7a44cae8423b7b9a454a862d15369eaf4b Mon Sep 17 00:00:00 2001
From: Stefan Penner <stefan.penner@gmail.com>
Date: Tue, 1 Sep 2009 15:23:56 -0500
Subject: [PATCH 2/2] fixed multiparameter_attributes from failing when being assigned via an assication_proxy
---
activerecord/lib/active_record/base.rb | 32 ++++++++++++++++++++------------
1 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index c17702d..62b87e8 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -2436,7 +2436,7 @@ module ActiveRecord #:nodoc:
@new_record = true
ensure_proper_type
self.attributes = attributes unless attributes.nil?
- self.class.send(:scope, :create).each { |att,value| self.send("#{att}=", value) } if self.class.send(:scoped?, :create)
+ assign_attributes(self.class.send(:scope, :create)) if self.class.send(:scoped?, :create)
result = yield self if block_given?
callback(:after_initialize) if respond_to_without_attributes?(:after_initialize)
result
@@ -2734,18 +2734,8 @@ module ActiveRecord #:nodoc:
attributes = new_attributes.dup
attributes.stringify_keys!
- multi_parameter_attributes = []
attributes = remove_attributes_protected_from_mass_assignment(attributes) if guard_protected_attributes
-
- attributes.each do |k, v|
- if k.include?("(")
- multi_parameter_attributes << [ k, v ]
- else
- respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
- end
- end
-
- assign_multiparameter_attributes(multi_parameter_attributes)
+ assign_attributes(attributes) if attributes and attributes.any?
end
# Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
@@ -2862,6 +2852,24 @@ module ActiveRecord #:nodoc:
end
private
+
+ # Assigns attributes, dealing nicely with both multi and single paramater attributes
+ # Assumes attributes is a hash
+
+ def assign_attributes(attributes={})
+ multiparameter_attributes = []
+
+ attributes.each do |k, v|
+ if k.to_s.include?("(")
+ multiparameter_attributes << [ k, v ]
+ else
+ respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
+ end
+ end
+
+ assign_multiparameter_attributes(multiparameter_attributes) unless multiparameter_attributes.empty?
+ end
+
def create_or_update
raise ReadOnlyRecord if readonly?
result = new_record? ? create : update
--
1.6.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment