diff --git a/lib/activerecord-postgres-array/activerecord.rb b/lib/activerecord-postgres-array/activerecord.rb index dd8be3b..92c62a7 100644 --- a/lib/activerecord-postgres-array/activerecord.rb +++ b/lib/activerecord-postgres-array/activerecord.rb @@ -96,6 +96,16 @@ def type_cast_code_with_array(var_name) end alias_method_chain :type_cast_code, :array + def type_cast_with_array(value) + if value.present? && type.to_s =~ /_array$/ + base_type = type.to_s.gsub(/_array/, '') + value.from_postgres_array(base_type.parameterize('_').to_sym) + else + type_cast_without_array(value) + end + end + alias_method_chain :type_cast, :array + # Adds the array type for the column. def simplified_type_with_array(field_type) if field_type =~ /^numeric.+\[\]$/ diff --git a/spec/array_ext_spec.rb b/spec/array_ext_spec.rb index 80f6a10..251c032 100644 --- a/spec/array_ext_spec.rb +++ b/spec/array_ext_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require 'activerecord-postgres-array/array' -describe "Array" do +describe Array do describe "#to_postgres_array" do it "returns '{}' if used on an empty array" do [].to_postgres_array.should == "'{}'" @@ -27,4 +27,11 @@ ["\\","\""].to_postgres_array.should == '\'{"\\\\","\\""}\'' end end + + describe "#from_postgres_array" do + subject(:array) { [:foo, :bar, :baz] } + it "returns the array itself" do + array.from_postgres_array.should eq array + end + end end \ No newline at end of file diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb index 6496b3e..f50489f 100644 --- a/spec/integration_spec.rb +++ b/spec/integration_spec.rb @@ -133,3 +133,14 @@ end end end + +describe DefaultArticle do + it "creates a model with defaults" do + article = DefaultArticle.create + article.reload + article.name.should == 'AbC' + article.author_ids.should == [1,2,3] + article.prices.should == [12.519267, 16.0] + article.defaults.should == ['foo', 'bar', 'baz qux'] + end +end diff --git a/spec/internal/app/models/default_article.rb b/spec/internal/app/models/default_article.rb new file mode 100644 index 0000000..76c6310 --- /dev/null +++ b/spec/internal/app/models/default_article.rb @@ -0,0 +1,3 @@ +class DefaultArticle < ActiveRecord::Base + serialize :serialized_column +end \ No newline at end of file diff --git a/spec/internal/db/schema.rb b/spec/internal/db/schema.rb index 9dd227a..07b767a 100644 --- a/spec/internal/db/schema.rb +++ b/spec/internal/db/schema.rb @@ -6,6 +6,7 @@ t.string_array :languages t.integer_array :author_ids t.float_array :prices + t.string_array :defaults, :default => ['foo', 'bar'] # To make sure we don't interfere with YAML serialization t.string :serialized_column @@ -14,4 +15,13 @@ t.hstore :hstore_column end add_hstore_index :articles, :hstore_column + + # Creating a new model table because we don't seem to be able to dump schema for hstore tables well + create_table(:default_articles, :force => true) do |t| + t.string :name, :default => 'AbC' + t.string_array :languages + t.integer_array :author_ids, :default => [1,2,3] + t.float_array :prices, :default => [12.519267, 16.0] + t.string_array :defaults, :default => ['foo', 'bar', 'baz qux'] + end end diff --git a/spec/schema_spec.rb b/spec/schema_spec.rb new file mode 100644 index 0000000..490eed1 --- /dev/null +++ b/spec/schema_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe "Schema" do + subject(:dump_stream) { StringIO.new } + + before { ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, dump_stream) } + + it "can dump the schema" do + dump_stream.string.should_not be_blank + end + + it "should dump the schema including the array types" do + dump_stream.string.should include("t.string_array") + dump_stream.string.should include("t.float_array") + dump_stream.string.should include("t.integer_array") + end + + it "should still dump columns with normal defaults correctly" do + dump_stream.string.should include(':default => "AbC"') + end + + it "should dump schemas including defaults for string arrays" do + dump_stream.string.should include(':default => ["foo", "bar", "baz qux"]') + end + + it "should dump schemas including defaults for integer arrays" do + dump_stream.string.should include(":default => [1, 2, 3]") + end + + it "should dump schemas including defaults for float arrays" do + dump_stream.string.should include(":default => [12.519267, 16.0]") + end +end \ No newline at end of file diff --git a/spec/string_ext_spec.rb b/spec/string_ext_spec.rb index b43a6f8..0fc9d8c 100644 --- a/spec/string_ext_spec.rb +++ b/spec/string_ext_spec.rb @@ -105,5 +105,23 @@ 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 'handles decimal content' do + "{15.49151, 16.0}".from_postgres_array(:decimal).should == [15.49151, 16.0] + end + + it 'handles float content' do + "{15.49151, 16.0}".from_postgres_array(:float).should == [15.49151, 16.0] + end + + it 'handles integer content' do + "{1,2,3}".from_postgres_array(:integer).should == [1,2,3] + end + + it 'handles timestamp content' do + t1 = Time.at(628232400) + t2 = Time.at(1362018690) + "{#{t1},#{t2}}".from_postgres_array(:timestamp).should == [t1, t2] + end end end \ No newline at end of file