2013-01-07 86 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