Skip to content

Commit

Permalink
modified multi-parameter attributes patch by fauxparse to behave cons…
Browse files Browse the repository at this point in the history
…istently with the way ActiveRecord handles timezones
  • Loading branch information
sskirby committed Sep 24, 2010
1 parent 3ca7055 commit c45be54
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 37 deletions.
1 change: 1 addition & 0 deletions lib/mongoid/extensions/date/conversions.rb
Expand Up @@ -16,6 +16,7 @@ def get(value)

def convert_to_time(value)
value = ::Date.parse(value) if value.is_a?(::String)
value = ::Date.civil(*value) if value.is_a?(::Array)
::Time.utc(value.year, value.month, value.day)
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/mongoid/extensions/time_conversions.rb
Expand Up @@ -29,6 +29,7 @@ def convert_to_time(value)
when ::String then time.parse(value)
when ::DateTime then time.local(value.year, value.month, value.day, value.hour, value.min, value.sec)
when ::Date then time.local(value.year, value.month, value.day)
when ::Array then time.local(*value)
else value
end
end
Expand Down
26 changes: 11 additions & 15 deletions lib/mongoid/multi_parameter_attributes.rb
Expand Up @@ -45,17 +45,7 @@ def process(attrs = nil)
begin
values = (values.keys.min..values.keys.max).map { |i| values[i] }
klass = self.class.fields[key].try(:type)
attributes[key] = if klass == DateTime
instantiate_time_object(*values).to_datetime
elsif klass == Date
Date.civil(*values)
elsif klass == Time
instantiate_time_object(*values).to_time
elsif klass
klass.new *values
else
values
end
attributes[key] = instantiate_object(klass, values)
rescue => e
errors << Errors::AttributeAssignmentError.new("error on assignment #{values.inspect} to #{key}", e, key)
end
Expand All @@ -64,16 +54,22 @@ def process(attrs = nil)
unless errors.empty?
raise Errors::MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
end

super attributes
else
super
end
end

protected
def instantiate_time_object(*values)
(Time.zone || Time).send(Mongoid::Config.instance.use_utc? ? :utc : :local, *values)
def instantiate_object klass, values
if klass == DateTime || klass == Date || klass == Time
klass.send(:convert_to_time, values)
elsif klass
klass.new *values
else
values
end
end
end
end
end
10 changes: 9 additions & 1 deletion spec/unit/mongoid/extensions/date/conversions_spec.rb
Expand Up @@ -68,7 +68,15 @@
it "converts to a utc time" do
Date.set(@date).should == Time.utc(@date.year, @date.month, @date.day)
end
end

context "when given an Array" do
before { @array = [@time.year, @time.month, @time.day] }

it "converts to a utc time" do
Date.set(@array).should == Time.utc(*@array)
Date.set(@array).utc_offset.should == 0
end
end
end

Expand Down Expand Up @@ -142,4 +150,4 @@
end
end
end
end
end
25 changes: 25 additions & 0 deletions spec/unit/mongoid/extensions/time_conversions_spec.rb
Expand Up @@ -108,6 +108,7 @@

it "converts to a utc time" do
Time.set(@date).should == Time.local(@date.year, @date.month, @date.day)
Time.set(@date).utc_offset.should == 0
end

context "when using the ActiveSupport time zone" do
Expand All @@ -127,6 +128,30 @@
end
end
end

context "when given an array" do
before { @array = [2010, 11, 19, 00, 24, 49] }

it "returns a time" do
Time.set(@array).should == Time.local(*@array)
end

context "when using the ActiveSupport time zone" do
before do
Mongoid::Config.instance.use_activesupport_time_zone = true
# if this is actually your time zone, the following tests are useless
Time.zone = "Stockholm"
end
after do
Time.zone = nil
Mongoid::Config.instance.use_activesupport_time_zone = false
end

it "assumes the given time is local" do
Time.set(@array).should == Time.utc(2010, 11, 18, 23, 24, 49)
end
end
end
end

describe ".get" do
Expand Down
36 changes: 15 additions & 21 deletions spec/unit/mongoid/multi_parameter_attributes_spec.rb
Expand Up @@ -3,28 +3,22 @@
describe Mongoid::MultiParameterAttributes do
describe "#process" do
context "creating a post" do
[ true, false ].each do |use_utc|
context "#{use_utc ? "with" : "without"} UTC" do
before do
Mongoid::Config.instance.use_utc = use_utc

@post = Post.new({
"created_at(1i)" => 2010,
"created_at(2i)" => 8,
"created_at(3i)" => 12,
"created_at(4i)" => 15,
"created_at(5i)" => 45
})
end
before do
@post = Post.new({
"created_at(1i)" => 2010,
"created_at(2i)" => 8,
"created_at(3i)" => 12,
"created_at(4i)" => 15,
"created_at(5i)" => 45
})
end

it "should set a multi-parameter Time attribute correctly" do
@post.created_at.should == Time.send(use_utc ? :utc : :local, 2010, 8, 12, 15, 45)
end
it "should set a multi-parameter Time attribute correctly" do
@post.created_at.should == Time.local(2010, 8, 12, 15, 45)
end

it "should not leave ugly attributes on the model" do
@post.attributes.should_not have_key("created_at(1i)")
end
end
it "should not leave ugly attributes on the model" do
@post.attributes.should_not have_key("created_at(1i)")
end
end

Expand Down Expand Up @@ -60,4 +54,4 @@
end

end
end
end

0 comments on commit c45be54

Please sign in to comment.