Permalink
Browse files

Merge pull request #123 from estei/master

Support for multi-parameter attributes
  • Loading branch information...
2 parents 819ddb7 + 2571791 commit 93c2fbd1437155344e6c75ad2a95d17f9bc85778 @samlown committed Feb 29, 2012
Showing with 96 additions and 4 deletions.
  1. +44 −3 lib/couchrest/model/properties.rb
  2. +5 −1 spec/fixtures/models/base.rb
  3. +47 −0 spec/unit/base_spec.rb
@@ -106,13 +106,21 @@ def find_property!(property)
# that have not been accepted.
def directly_set_attributes(hash, mass_assign = false)
return if hash.nil?
+
+ multi_parameter_attributes = []
+
hash.reject do |key, value|
- if self.respond_to?("#{key}=")
- self.send("#{key}=", value)
+ if key.to_s.include?("(")
+ multi_parameter_attributes << [ key, value ]
+ false
+ elsif self.respond_to?("#{key}=")
+ self.send("#{key}=", value)
elsif mass_assign || mass_assign_any_attribute
self[key] = value
end
end
+
+ assign_multiparameter_attributes(multi_parameter_attributes, hash) unless multi_parameter_attributes.empty?
end
def directly_set_read_only_attributes(hash)
@@ -125,7 +133,40 @@ def directly_set_read_only_attributes(hash)
end
end
-
+ def assign_multiparameter_attributes(pairs, hash)
+ execute_callstack_for_multiparameter_attributes(
+ extract_callstack_for_multiparameter_attributes(pairs), hash
+ )
+
+ end
+ def execute_callstack_for_multiparameter_attributes(callstack, hash)
+ callstack.each do |name, values_with_empty_parameters|
+ if self.respond_to?("#{name}=")
+ casted_attrib = send("#{name}=", values_with_empty_parameters)
+ unless casted_attrib.is_a?(Hash)
+ hash.reject { |key, value| key.include?(name.to_s)}
+ end
+ end
+ end
+ hash
+ end
+
+ def extract_callstack_for_multiparameter_attributes(pairs)
+ attributes = { }
+
+ pairs.each do |pair|
+ multiparameter_name, value = pair
+ attribute_name = multiparameter_name.split("(").first
+ attributes[attribute_name] = {} unless attributes.include?(attribute_name)
+ attributes[attribute_name][find_parameter_name(multiparameter_name)] ||= value
+ end
+ attributes
+ end
+
+ def find_parameter_name(multiparameter_name)
+ position = multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
+ {1 => :year, 2 => :month, 3 => :day, 4 => :hour, 5 => :min, 6 => :sec}[position]
+ end
module ClassMethods
@@ -161,4 +161,8 @@ class WithScopedUniqueValidation < CouchRest::Model::Base
validates_uniqueness_of :title, :scope => :parent_id
end
-
+class WithDateAndTime < CouchRest::Model::Base
+ use_database TEST_SERVER.default_database
+ property :exec_date, Date
+ property :exec_time, Time
+end
View
@@ -81,6 +81,53 @@ def set_name; self.name = "foobar"; end
@doc.name.should eql("foobar")
end
end
+ describe "multipart attributes" do
+ context "with valid params" do
+ it "should parse a legal date" do
+ valid_date_params = { "exec_date(1i)"=>"2011",
+ "exec_date(2i)"=>"10",
+ "exec_date(3i)"=>"18"}
+ @obj = WithDateAndTime.new valid_date_params
+ @obj.exec_date.should_not be_nil
+ @obj.exec_date.should be_kind_of(Date)
+ @obj.exec_date.should == Date.new(2011, 10 ,18)
+ end
+
+ it "should parse a legal time" do
+ valid_time_params = { "exec_time(1i)"=>"2011",
+ "exec_time(2i)"=>"10",
+ "exec_time(3i)"=>"18",
+ "exec_time(4i)"=>"15",
+ "exec_time(5i)"=>"15",
+ "exec_time(6i)"=>"15",}
+ @obj = WithDateAndTime.new valid_time_params
+ @obj.exec_time.should_not be_nil
+ @obj.exec_time.should be_kind_of(Time)
+ @obj.exec_time.should == Time.utc(2011, 10 ,18, 15, 15, 15)
+ end
+ end
+
+ context "with invalid params" do
+ before(:each) do
+ @invalid_date_params = { "exec_date(1i)"=>"2011",
+ "exec_date(2i)"=>"foo",
+ "exec_date(3i)"=>"18"}
+ end
+ it "should still create a model if there are invalid attributes" do
+ @obj = WithDateAndTime.new @invalid_date_params
+ @obj.should_not be_nil
+ @obj.should be_kind_of(WithDateAndTime)
+ end
+ it "should not crash because of an empty value" do
+ @invalid_date_params["exec_date(2i)"] = ""
+ @obj = WithDateAndTime.new @invalid_date_params
+ @obj.should_not be_nil
+ @obj.exec_date.should_not be_kind_of(Date)
+ @obj.should be_kind_of(WithDateAndTime)
+ end
+ end
+ end
+
describe "ActiveModel compatability Basic" do

0 comments on commit 93c2fbd

Please sign in to comment.