2012年11月2日 星期五

[宅] facebook開發日誌 - facebook API入門(1)

在開發facebook相關應用的時候一直沒有好好地做一個整理,
最近有個應用需要query使用者在timeline上發的照片,正好趁此筆記一下FQL這個東東結果一不小心就寫成API的介紹文。

前言

facebook提供開發者四種API:

  • Login
  • Graph API
  • FQL
  • Legacy REST

但在開始介紹API之前必須先提授權碼(access token)的概念,讓我們使用Graph API Explorer這個好用的facebook開發工具來一步一步了解access token的概念。
首先,登入 http://developers.facebook.com/tools/explorer/ ,你會看到以下畫面:


先在"GET"旁邊的輸入欄打"ME",然後送出。如果你從來沒有使用過這個工具的話,就會看到以下訊息:
{
  "error": {
    "message": "An active access token must be used to query information about the current user.", 
    "type": "OAuthException", 
    "code": 2500
  }
}
這代表你沒有權限存取現在的facebook使用者(你自己)的資料,但在取得這個權限之前,我們先來做另一個小試驗:在同一個地方打"zuck",相信你會看到以下訊息:
{
  "id": "4", 
  "name": "Mark Zuckerberg", 
  "first_name": "Mark", 
  "last_name": "Zuckerberg", 
  "link": "http://www.facebook.com/zuck", 
  "username": "zuck", 
  "gender": "male", 
  "locale": "en_US"
}
眼尖的你可能馬上就發現了這是facebook創辦人Mark Zuckberg的基本資料,酷吧!
但是為什麼自己的資料拿不到,卻可以拿到別人的資料勒?因為Zuckberg是特例嗎?一定是這樣子的吧哈哈哈!




其實不是特例,因為你打別人的名字也是一樣,Peter、John、Mary之類的菜市場名都可以試試,甚至你如果曾在facebook上取過英文也可以試試看....

"X!真的可以耶!這是怎麼回事!?"

這是因為"ME"是取得任何正在瀏覽這個網頁的facebook user的參數,這樣開發者就可以很靈活的寫相關應用。所以雖然基本上不用任何acess token也可以取得特定使用者的基本資料(使用特定ID),但要用ME來靈活運用使用者資料就得要取得你的授權(acess token)了。

所以前面出現的"OAuthException"就是因為Graph API Explorer還沒取得你的授權,所以不能用ME來取得你的資料的錯誤提示。現在我們就點選Graph API Explorer頁面上的"取得存取代碼"這個按鈕來讓它取得你的授權,然後就會彈出這個視窗:


上面佈滿了各種選項,代表了你要讓這個應用程式存取那些權限,點選"user_about_me"以後送出就會看到熟悉的畫面:


現在你應該知道facebook app的登入畫面是怎麼來的了

之後Graph API Explorer就可以使用你的基本資料,輸入"ME"之後也會順利的出現相關訊息,這個簡單的步驟解釋了app從登入到使用你的資料的基本流程,也是facebook應用開發者的第一步。

而Graph API Explorer可不只是facebook開發的入門工具,畢竟facebook所提供的API還不少,所以即使是有開發經驗的工程師也會時常使用這個工具來驗證自己的邏輯是否可以正確運作。

身為一個開發者,只知道這些是不夠的,請讓我們往下一篇邁進!

[宅] 宅男臥軌日記(7) - .nil? , .empty?, .blank? 的區別


.nil? 和.empty? 是ruby的方法,而.blank? 是rails的方法
這三個method都是判斷是否為空值。


.nil?

判斷對象是否存在(nil)。不存在的對像都是nil的

.empty?

對象已經存在,判斷是否為空字串。
比如一個字符串是否為空串,或者一個數組中是否有值。

.blank?

具有以上兩個method的特性,railsAPI:
An object is blank if it’s false, empty, or a whitespace string. For example, “”, “ ”, nil, [], and {} are all blank.

2012年10月30日 星期二

[宅] javascript筆記(8) - 全域變數&匿名函數

最近在PTT ajax版看到一篇非常不錯的筆記,正好把之前雜亂無章的理解給重新整理了一遍。
原文:http://disp.cc/b/11-4CrK (Knuckles@PTT)

使用全域變數時,由於要往上查找全域,造成效能低落,所以應盡量避免大量使用。
文中作者提到匿名變數的方法:
(function(x){ /*...*/ })(x);
自己寫lib時也曾用這個方法來寫。雖然在匿名函式外看不到裡面所定義的function和變數,但是可以在匿名函式內綁定function和外部觸發事件。也可以將匿名函式裡特定物件設為全域變數,由於scope的關係,外面看的到這個object,這個object也看得到匿名函式裡的其他function和變數。我們以ember.js開頭的一小段程式碼來做了解:
(function() {
  ...
  /**
  @class Ember
  */
  if ('undefined' === typeof Ember) {
    Ember = {};

    if ('undefined' !== typeof window) {
      window.Em = window.Ember = Em = Ember;
    }
  }
  ...
})();
當一個全域變數被定義時,等於是加入到window這個object底下。所以Ember={}跟window.Ember={}是一樣的。
而Ember這個object可能有很多function,例如Ember.deprecate,就可以在全域被看到。但如果Ember.deprecate需要使用一些varible或function,這些東西都必須放在Ember所被定義的匿名函式裡。

從Ember的寫法也能看出來,當include一個lib進來的時候,通常會定義一個特定名稱的Object再將相關的變數及函式都塞在這個Object底下,避免一不小心就重複命名了。

2012年10月29日 星期一

[宅] 宅男臥軌日記(6) - %Q, %q, %W, %w, %x, %r, %s

%Q( )

能將括弧中的內容轉成雙引號框成的字串,
而%Q後面未必要用括弧,也可以是!、[ ]、+等符號,例如:
%Q! !、%Q[ ]、%Q+ +

%q( )

功能跟大寫Q差不多,只是將內容換成單引號框成的字串。

※Notice: 在Ruby中定義字串時最好使用雙引號,因為只有在雙引號中才能使用#{var}來嵌入程式碼

%W( )

將括弧中的內容轉換成雙引號的string array,看下面的程式碼會更容易理解
>> %W(#{foo} Bar Bar\ with\ space)
=> ["Foo", "Bar", "Bar with space"]

%w( )

和大寫W是差不多的,只是將雙引號變單引號


%r( )

正規表示式,如下:
>> %r(/home/#{foo})
=> "/\\/home\\/Foo/"

%s( )

用於符號(symbol)
>> %s(foo)
=> :foo
>> %s(foo bar)
=> :"foo bar"
>> %s(#{foo} bar)
=> :"\#{foo} bar"

[宅] 宅男臥軌日記(5) - 資料表關聯方法: includes & joins

用一行程式碼大家應該就能明白:
user = User.includes(:authorizations).where("authorizations.provider" => 'facebook' , "authorizations.uid" => uid).first

includes跟joins功能挺像,引用ihower大大的部落格內的說法:
透過joins抓出來的event物件是沒有包括其關連物件的。如果需要其關連物件的資料,會使用includes。(出處:http://ihower.tw/rails3/activerecord-relationships.html)
但有一個差別在於includes所找到的model內的readonly屬性會是false,而joins所回傳的將是true。這造成了很大的影響:"用joins所找到的model不能被修改",所以當試圖修改model的值時,會回傳ActiveRecord::ReadOnlyRecord error.

2012年10月28日 星期日

[宅] 宅男臥軌日記(4) - class及instance的method定義

在定義class中的method時,要注意究竟是給instance使用還是class

當以如下方式定義method時,代表這個method是要給class的instance使用
class User
  def say_hello
    puts "Hello"
  end
end
所以當執行User.say_hello時就會發生找不到method的情況,但在以下情形會是正常的:
user = User.new
user.say_hello
=>"Hello"

所以如果一個method希望能被class所使用,必須以以下方式定義:
class User
  def User.say_hello
    puts "Hello"
  end
end
或是
class User
  def self.say_hello
    puts "Hello"
  end
end
當然也可以用extend從module中mixin進來

[宅] 宅男臥軌日記(3) - load或require路徑

在ROR中,若想load或require其他module進來,要將module放在哪哩?
我們可以看看config/application.rb中的設定:
# Custom directories with classes and modules you want to be autoloadable.
    config.autoload_paths += %W(#{config.root}/lib)
上面這一段就是指定module所在的資料夾,其中config.root是指config/的母目錄。所以這樣的設定之下,我們就要將module放在lib/底下,在class中引用module時,ROR就會知道要到lib/底下找。

要注意的是檔名如果有多字都是小寫,字和字之間用底線區隔,像這樣:
omniauth_callbacks.rb

裡面的module得要這樣命名:
module OmniauthCallbacks