Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a postgres db with each row representing an "index" (just a name not the keyword). For each market, there is an attribute "stats" thats a two dimensional array of numbers that I put into the db from an external source.

 create_table "indices", force: true do |t|
    t.string  "name",                     null: false
    t.float   "returns",     default: [],              array: true
    t.float   "navs",        default: [],              array: true
    t.float   "stats",       default: [],              array: true
    t.string  "updated_at"
    t.string  "created_at"
    t.integer "idx_type_id"
  end

My problem is how do I get the stats values out of the db and into my rails program?

In the console, I tried the following code:

a = Index.find(1)
a.name
a.stats

It correctly gets the name attribute, but I get the following error for the stats attribute

 undefined method `to_f' for ["0.259854651130407", "0.261425018884344"]:Array

The numbers shown inside the square brackets are the values of the first row of the 2D array. Any ideas?

EDIT: I'm running rails 4.0.1 and here's the original migration to create the table. Is there a syntax error in here or something?

class CreateIndices < ActiveRecord::Migration
  def change
    create_table :indices, {:id => false} do |t|
      t.string :name
      t.float :returns, array: true, default: []
      t.float :navs, array: true, default: []
      t.float :sharpe

      t.timestamps
    end

    execute "ALTER TABLE indices ADD PRIMARY KEY (name);"
  end
end

EDIT 2: Here is the output from the following query in psql

query:

select stats from indices where id < 3 

output:

stats
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------
 {{0.259854651130407,0.261425018884344},{0.114409534648231,0.113829156756227},{2.27126744225792,2.28284789710692},{0.0562802038101342,0.0561701509132937},{4.61715902819129,4.65416265816855},{0.0
92128059492271,0.0921734852013666},{2.82058096699852,2.81919090465893},{0.0292770008925915,0.0291771074372238},{8.87572644765545,8.95993612275702}}
 {{0.259854651130407,0.261425018884344},{0.114409534648231,0.113829156756227},{2.27126744225792,2.28284789710692},{0.0562802038101342,0.0561701509132937},{4.61715902819129,4.65416265816855},{0.0
92128059492271,0.0921734852013666},{2.82058096699852,2.81919090465893},{0.0292770008925915,0.0291771074372238},{8.87572644765545,8.95993612275702}}
(2 rows)
share|improve this question
    
What version of Rails is this? –  mu is too short Dec 18 '13 at 21:34
    
i'm running rails 4.0.1 –  jhlu87 Dec 18 '13 at 22:02
    
Check the table definition inside the database using \d indices from within psql. –  mu is too short Dec 18 '13 at 22:13
    
In table definition it has type as double precision[], and modifiers as default '{}'::double precision[]. Also does it matter that it's declared as a 1D array when I have a 2D array, in the PG docs it seemed to imply that it doesn't since it doesn't actually enforce dimensions or lengths of arrays. –  jhlu87 Dec 18 '13 at 22:17
    
So the whole array looks more like [[0.25, 0.26]] than [0.25, 0.26]? Maybe including some of the select stats from indices data from psql would help clarify things. My current guess is that Rails4 only understands one dimensional arrays. –  mu is too short Dec 18 '13 at 22:24

1 Answer 1

A column of float type cannot store arrays, it can only store floats.

You could either make the column type text and then serialize the columm in your model via serialize :stats, Array or you can create the table via add column :indices, :stats, :text, :array => true.

But in your current state, you have told the database the column is a float type, not array so the ORM is treating the data as such when it reads/writes.

share|improve this answer
    
ok so just to be clear, what you're saying is rails only supports arrays of type string and not other datatypes? –  jhlu87 Dec 18 '13 at 21:05
    
No, what I am saying is that you told rails that the schema for your table was a float field, when its really an array field so that is why activerecord is trying to treat it as a float. –  cpjolicoeur Dec 18 '13 at 21:06
    
I see, but from your suggested solutions, it seems that I cannot declare that field to be an array of floats. I have to declare it as a text array and then convert from text to floats at some later point. Is that correct? –  jhlu87 Dec 18 '13 at 21:10
    
I believe you could declare as :integer, :array => true, or :decimal, :array => true or any field type. Also, you can just serialize it yourself into an array of any type. Serialized fields use text columns by default, that is why my example had it that way –  cpjolicoeur Dec 18 '13 at 21:13
    
ps, google is your friend here for this case as well –  cpjolicoeur Dec 18 '13 at 21:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.