5

I use hstore with Postgres 9.2 and Rails 3.2 to store my object like this:

class User
  user_hstore = {:user_id =>"123", :user_courses => [1,2,3]}
end

Now, when I retrieve user_courses, I get a string like this: '[1, 2, 3]'

How do I convert this string to Rails array? Better yet, is there a way to store an array within a hstore object so that Rails will automatically retrieve it as array type?

5
  • Despite my earlier answer, it's Postgres offers no support for anything beyond string values. I suspect given the overlap between serialize and hstore functionality, there isn't a readymade solution for this. Commented Jun 11, 2013 at 22:40
  • 1
    The team is working on improving this for PostgreSQL 9.4, which will hopefully have a fully indexable, nestable, json-compatible replacement for hstore. See lwn.net/Articles/553256 (currently subscriber only, will be readable to everyone next week sometime). Commented Jun 12, 2013 at 3:50
  • Hi Craig: thanks for the info. Silly question: Rails needs to support this feature too before we can use it, correct? Commented Jun 12, 2013 at 3:58
  • Yes, you'll have to wait for Rails (or a plugin) to properly support the new hstore stuff. OTOH, there's also a JSON data type in PostgreSQL. Commented Jun 12, 2013 at 4:40
  • Yes, there is a gem for that: store_complex. Still under development. Commented Oct 24, 2014 at 0:22

4 Answers 4

11
JSON.parse "[\"1018\", \"1037\", \"1045\", \"1042\"]"
#=> ["1018", " 1037", " 1045", " 1042"]
Sign up to request clarification or add additional context in comments.

Comments

9

Why not just use eval?

eval('[1, 2, 3]')
#=> [1, 2, 3]

Obviously, don't do this on arbitrary or user inputted data, but on an array of integers as you've displayed, it's perfectly safe.

Comments

2

To convert it to an array:

user_courses.gsub('[', '').gsub(']', '').split(",")

To make retrieval simpler, you can store it as a string by doing

user_hstore = {:user_id =>"123", :user_courses => '1,2,3'}

Comments

1

Just to throw another hat into the ring, this accomplishes the same as Vimsha's answer but is a little more short and sweet you could do:

"[1,2,3,4]"[1..-2].split(",")

which in your case could be:

user_courses[1..-2].split(",")

Edit: If speed is a concern I did a quick benchmark which can be found here. Doing only a few items is not a very big difference but 10,000 items + you can start seeing a difference. This is at 100,000 items:

  # "[1,2,3,4]"[1..-2].split(",")
  0.110000   0.000000   0.110000 (  0.114739)

  # "[1,2,3,4]".gsub("[", "").gsub("", "]").split(",")
  1.080000   0.000000   1.080000 (  1.081227)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.