2013-01-07 45 views
0

我正试图学习考拉宝石来链接Facebook与我的Ruby on Rails应用程序。我已经开始掌握它了,但我遇到了一些严重的心理障碍!如何处理数组内的信息?

def friends 
    facebook.fql_query("SELECT uid,username, is_app_user, name, pic_square FROM user WHERE uid IN(SELECT uid2 FROM friend WHERE uid1 = me()) AND is_app_user=1"); 
rescue Koala::Facebook::APIError => e 
    logger.info e.to_s 
    nil 
end 

因此,首先,我使用FQL来搜索用户朋友。它返回的朋友是current_user的朋友的详细信息,登录到应用程序的用户的详细信息以及与我的应用程序相关的用户的详细信息。

def friends_realname 
    names = friends.select {|f| f["is_app_user"] }.map {|f| f["name"]} 
    names.each { |name| puts name} 
end 

我选择上面的“用户的朋友也使用我的应用程序的名称 - 并映射到一个数组。这将返回一个数组:["friend1's name", "friend2's name"]

def friends_avatars 
    @avatars = friends.select {|f| f["is_app_user"] }.map {|f| f["pic_square"]} 
end 

我试图做同样的,但这些返回同一用户的个人资料图片的URL。它返回一个数组:

["http://www.example.com/example.jpg", "http://www.example2.com/example2.jpg"] 

我想从返回的数组中格式化信息。所以,对于真实姓名,我不想返回实际的数组,而是要返回一个名称列表。而且,显然对于图像,我实际上是想将这些图像放在视图中,而不是返回一组图像url。

我想我需要遍历每个这些数组,然后使用each方法对数组中的每个字符串执行一些操作,例如puts img_tag

将这样的事情是可能的?:

def friends_avatars 
    @avatars = friends.select {|f| f["is_app_user"] }.map {|f| f["pic_square"]} 
    @avatars.each { |avatar| puts image_tag "#{avatar}}"} 
end 

刚刚意识到image_tag是一个辅助方法,所以我不能有使用它。

我也是在一个视图文件试过这样:

<% for url in @avatars do %> 
    <%= puts "#{url}" %> 
<% end %> 

将返回:

undefined method `each' for nil:NilClass 

每当我试图将一个阵列内返回字符串,他们只是返回数组。不确定该从哪里出发。

+0

我已经按照Phrogz建议(感谢队友) - 和一些测试后,我已经想通了,为什么我出错。当我测试一个方法的类时 - 它返回一个Array类。当我给这个方法一个变量名时 - 该变量名返回NilClass。 – Samwise

回答

1
app_users = friends.select{ |f| f["is_app_user"] } 
@names_and_pictures = app_users.map{ |f| [ f["name"], f["pic_square"] ] } 

这就造成了两个元素的数组的数组,即

[ [ "Bob", "http://foo" ], [ "Jim", "http://bar" ] ] 

然后你就可以在并行重复这些:

<% @names_and_pictures.each do |name,pic_url| %> 
    <li><%=name%><img src="<%=pic_url%>"></li> 
<% end %> 

请注意,你不使用你的puts视图,因为此功能将信息输出到控制台。相反,您只需使用<%= ... %>将Ruby代码强制为字符串值并将其注入输出中的适当位置即可。


你原来的代码是好的(只要你用好的命名方法包装你的代码),但是做得太多了。

def friends_realname 
    names = friends.select {|f| f["is_app_user"] }.map {|f| f["name"]} 
    names.each { |name| puts name} 
end 

有没有必要在这里的名字puts。该方法只是返回正确的值,因为each返回刚刚迭代的项目。你的方法一样可以有效地写为:

def friends_realname 
    friends.select {|f| f["is_app_user"] }.map {|f| f["name"]} 
end 

def friends_avatars 
    friends.select {|f| f["is_app_user"] }.map {|f| f["pic_square"]} 
end 

如果你碰巧要保留这些方法,您可以通过使用Array#zip两个数组合并为一个:

names = friends_realname    # One flat array 
avatars = friends_avatars    # Another flat array 
@names_and_pictures = names.zip(avatars) # An array of two-element arrays 
+0

干杯。我仍然得到一个“未定义的方法'每个'为零:NilClass”错误 – Samwise

+0

@Samswise对不起,我没有使代码成为一个实例变量。编辑。 – Phrogz

+0

我注意到了:)我在测试它之前解决了这个问题,它仍然存在nilclass错误 - 当我遇到这种类型的错误时,我只是被卡住了! – Samwise

0

您的通话总是映射返回一个数组。所以当你这样做:

@avatars = friends.select {|f| f["is_app_user"] }.map {|f| f["pic_square"]} 

你得到一个字符串数组。对于您的观点的目的,你可以做这样的事情:

<% @avatars.each do |url| %> 
    <%= puts "#{url}" %> 
<% end %> 

希望帮助

+0

在这里使用'puts'在服务器上是多余的和嘈杂的。此外,使用字符串插值来放置一个字符串(或任何值)是完全不必要的。 'puts'和'<%= ... %>'都会自动在任何非字符串值上调用'to_s'。 – Phrogz

+0

感谢您花时间回答Scott,这不是我一直在做的事吗? (在我的问题结尾?) - 不幸的是,我仍然遇到同样的错误! – Samwise

+0

@Progrog - 道歉,从问题复制粘贴错误。 – plasticide