0

I'm designing a REST API with Ruby and Sinatra. Only one problem I'm having: I'm trying to iterated over an array of posts selected from MySQL. The format is

[{:post => "Hello, world!", :comments => [{:author => "user1", :content => "Goodbye, world!"}]}, ...]

So, it's an array with a hash with the content post and comments, and the comments key has another array and hash(es) containing the author and content of the comment.

I have the following code pulling an array of posts from MySQL (returned in an array with hashes in it), and then iterating over those hashes. For each hash in the array, it gets the post ID and queries MySQL for any comments associated with that post. It then pushes the post and the comments to a hash, which is the pushed to an array that is returned.

def get_post(id = 'null', profile = 'null', owner = 'null')
        r = Array.new
        x = Hash.new
        p = self.query("SELECT * FROM `posts` WHERE `id` = '#{id}' OR `post_profile` = '#{profile}' OR `post_owner` = '#{owner}'")
        p.each do |i|
            x[:post] = i
            x[:comments] = self.query("SELECT * FROM `comments` WHERE `post` = '#{i["id"]}'")
            r.push(x)
        end
        return r
end

The odd thing is is that I can use a puts statement in the loop, and I'll get the individual posts

Ex:

r.push(x)
    puts x

But the array (r) just contains the same data over and over again. Sorry for such a long post, I just wanted to be thorough.

1 Answer 1

2

You keep pushing the same Hash instance onto the array, rather than creating new hashes. Try this:

def get_post(id = 'null', profile = 'null', owner = 'null')
  p = self.query("SELECT * FROM `posts` WHERE `id` = '#{id}' OR `post_profile` = '#{profile}' OR `post_owner` = '#{owner}'")
  p.map do |i|
    {
      post: i,
      comments: self.query("SELECT * FROM `comments` WHERE `post` = '#{i["id"]}'")
    }
  end
end

What this does is loop through the posts (with map rather than each, as I'll explain in a moment), and for each posts, returns a new hash consisting of your desired data. The map method collects all the return values from the loop into an array, so you don't have to do any manual array management.

Sign up to request clarification or add additional context in comments.

4 Comments

Okay, I tried that. It lists only the posts in individual hashes. No comments whatsoever.
Are you sure that you're using map rather than each?
In other words, the same thing db.query returns.
Yes: p.map do |i| { post: i, comments: self.query("SELECT * FROM comments WHERE post = '#{i["id"]}'") } end

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.