我正在使用Ruby和Sinatra设计REST API。我只有一个问题: 我正在尝试迭代从MySQL中选择的一系列帖子。 格式为
[{:post => "Hello, world!", :comments => [{:author => "user1", :content => "Goodbye, world!"}]}, ...]
因此,它是一个带有内容发布和注释的哈希的数组,而注释键有另一个包含注释的作者和内容的数组和哈希值。
我有以下代码从MySQL中提取一系列帖子(在包含哈希的数组中返回),然后迭代这些哈希值。对于数组中的每个哈希,它获取帖子ID并查询MySQL以查找与该帖子相关的任何注释。然后它将帖子和注释推送到一个哈希,这被推送到一个返回的数组。
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
奇怪的是我可以在循环中使用puts语句,我会得到个别帖子
前:
r.push(x)
puts x
但是数组(r)只是一遍又一遍地包含相同的数据。对不起这么长的帖子,我只想彻底。
答案 0 :(得分:2)
您不断将相同的Hash实例推送到阵列上,而不是创建新的哈希值。试试这个:
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
这样做会循环播放帖子(使用map
而不是each
,我会在稍后解释一下),并为每个帖子返回 new 哈希由您想要的数据组成。 map
方法将循环中的所有返回值收集到一个数组中,因此您不必进行任何手动数组管理。