From 1e8398de14f7b3d06788941f2a06a07c8df51e86 Mon Sep 17 00:00:00 2001 From: Louis Simoneau Date: Thu, 11 Apr 2013 22:35:36 +1000 Subject: [PATCH] Preserve nil values when typecasting --- lib/activerecord-postgres-array/string.rb | 20 ++++----- spec/string_ext_spec.rb | 51 ++++++++++++++++++++++- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/lib/activerecord-postgres-array/string.rb b/lib/activerecord-postgres-array/string.rb index f3fd3c6..815dbe3 100644 --- a/lib/activerecord-postgres-array/string.rb +++ b/lib/activerecord-postgres-array/string.rb @@ -26,16 +26,16 @@ def from_postgres_array(base_type = :string) res == 'NULL' ? nil : res end - if base_type == :decimal - elements.collect(&:to_d) - elsif base_type == :float - elements.collect(&:to_f) - elsif base_type == :integer || base_type == :bigint - elements.collect(&:to_i) - elsif base_type == :timestamp - elements.collect(&:to_time) - else - elements + typecast = { + :decimal => :to_d, + :float => :to_f, + :integer => :to_i, + :bigint => :to_i, + :timestamp => :to_time + }.fetch(base_type,false) + + elements.map do |e| + typecast ? e.try(typecast) : e end end end diff --git a/spec/string_ext_spec.rb b/spec/string_ext_spec.rb index b43a6f8..4a40495 100644 --- a/spec/string_ext_spec.rb +++ b/spec/string_ext_spec.rb @@ -105,5 +105,54 @@ it 'correctly handles multi line content' do "{A\nB\nC,X\r\nY\r\nZ}".from_postgres_array.should == ["A\nB\nC", "X\r\nY\r\nZ"] end + + it "returns NULL values as nil" do + "{NULL,on,Rails}".from_postgres_array.should == [nil, "on", "Rails"] + end + + context "with a base_type of :decimal" do + it "returns decimal numbers" do + "{1.1,2.1,3.1}".from_postgres_array(:decimal).should eql [1.1,2.1,3.1] + end + + it "returns NULL values as nil" do + "{NULL,2.1,3.1}".from_postgres_array(:decimal).should eql [nil, 2.1, 3.1] + end + end + + context "with a base_type of :integer" do + it "returns integers" do + "{1,2,3}".from_postgres_array(:integer).should eql [1,2,3] + end + + it "returns NULL values as nil" do + "{NULL,2,3}".from_postgres_array(:integer).should eql [nil, 2, 3] + end + end + + context "with a base_type of :float" do + it "returns floats" do + "{1,2,3}".from_postgres_array(:float).should eql [1.to_f,2.to_f,3.to_f] + end + + it "returns NULL values as nil" do + "{NULL,2,3}".from_postgres_array(:float).should eql [nil, 2.to_f, 3.to_f] + end + end + + context "with a base_type of timestamp" do + it "returns time objects" do + '{"2004-10-19 10:23:54","2004-10-19 10:23:54"}'.from_postgres_array(:timestamp).should eql [ + "2004-10-19 10:23:54".to_time, + "2004-10-19 10:23:54".to_time + ] + end + + it "returns NULL values as nil" do + '{NULL,"2004-10-19 10:23:54"}'.from_postgres_array(:timestamp).should eql [ + nil, "2004-10-19 10:23:54".to_time + ] + end + end end -end \ No newline at end of file +end