2011年9月16日 星期五

Google+ API 與 php

image

如果你沒有用過 Facebook API,那建議你可以先閱讀底下的文章釐清一些觀念

透過 Facebook API,讓你的 Facebook Application 發佈動態消息

 

Google+ API 已經可以使用囉!但目前只開放讀取部分資訊。

image

 

其實照著 Google+ 的文件進行就可以了,大概分幾個步驟:

 

這裡註冊你的 Google Application,註冊方式可以參考這裡

 

特別要注意的是,如果你用的是 php 的 Library,這個步驟結束之後…

 

要記得把 Redirect URI 改成這樣(實際上還是得以你放置的路徑為主,這個例子,我是將 index.php 放置在 www root 底下)

image

 

這裡可以看到等會需要輸入的資訊(黃色框住的部分)

image

 

這裡打開你的 Google+ API。

image 

 

這裡下載你使用的語言的 Library,這個範例是用 php 完成的(但 Ruby 的部分,我也測試過)

image

 

接著把 google-plus-php-client.zip 跟 google-plus-php-starter.zip 解壓縮到 Apache Web 的根目錄下。

SNAGHTML1efe26c

 

打開 index.php 填寫剛剛申請獲得的資訊。

image

 

打開 localhost 就完成囉!

SNAGHTML1fb85bc

 

如果操作過程中,出現了

CURL Error 60: SSL certificate problem, verify that the CA cert is OK.
Details: error:14090086:SSL routines
SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

的錯誤,可以參考底下這個網站解決!

http://richardwarrender.com/2007/05/the-secret-to-curl-in-php-on-windows/

Ruby on Rails 搜尋資料建立的日期範圍

在 RoR 建立 Model 的時候,它會自動幫 table 補上三個欄位:id, created_at, updated_at。可以利用

 

created_at, updated_at classActiveSupport::TimeWithZone,要特別注意的是每種時間 class 基準上的不同。

 

我們如果在頁面上這樣設計與搜尋:

image

 

而我們希望利用 created_at 搜尋到 「2011-9-16 00:00:00」 ~ 「2011-9-16 23:59:59」(不包含 2011-9-17 00:00:00) 的資料,那麼 controller 這邊應該要這樣處理。

程式碼

 
@start_date_year = params[:search][:start_date_year]
@start_date_month = params[:search][:start_date_month]
@start_date_day = params[:search][:start_date_day]
@end_date_year = params[:search][:end_date_year]
@end_date_month = params[:search][:end_date_month]
@end_date_day = params[:search][:end_date_day]
 
Model.where(
    :created_at =>
        ("#{@start_date_year}-#{@start_date_month}-#{@start_date_day}".to_date.to_time)..
        (("#{@end_date_year}-#{@end_date_month}-#{@end_date_day}".to_date + 1).to_time - 1
)

 

主要是利用 to_date 將字串轉換為 class Date 方便 +1 day,再利用 to_time 轉換為 class Time 方便 –1 second,此時 class Timeclass ActiveSupport::TimeWithZone 是同一個時間基準(Date 快了 8 hours ,時區的關係),便可直接比對。

2011年9月11日 星期日

Ruby on Rails 的整合測試 (Integration testing)

撰寫自動化測試是寫程式非常重要的一環,在 Ruby 裡有許多的測試框架,但最多人推崇的非 RSpec 莫屬。

關於 RSpec 的介紹,可以參考:

 

但若要完成整合測試,光靠 RSpec 可能還是有點不足,這時我們可以配合 Capybara 做更完整的測試。

Capybara 會偷開 Server (rails server),然後讓測試程式真的訪問我們所寫的 Web,因此所得到的互動結果是真實發生的狀況。

這個網站有非常清楚關於 RSpecCapybara 的教學

http://opinionated-programmer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/

 

實際寫起來可以像這樣

#encoding: utf-8
require 'spec_helper'
 
describe '活動頁面' do
  it '第一次進入此頁面,應該跳轉至註冊頁面' do
    visit '/campaigns'
    page.current_url.should =~ %r(http://[^/]+/sign_up)
  end
  
  it '實際註冊後,應該跳轉至登入頁面' do
    visit '/sign_up'
    fill_in 'user_email', :with => 'root@example.com'
    fill_in 'user_password', :with => 'root'
    fill_in 'user_password_confirmation', :with => 'root'
    click_on '註冊'
    
    page.current_url.should =~ %r(http://[^/]+/log_in)
  end
end

 

看了上面的例子,像不像在寫 spec 一樣呀?其實這個 spec 是可以拿來測試的喔!

 

其它

如果需要指定測試 Server 開啟在指定 port 的話,可以下達以下指令

Capybara.server_port = 3000

要回到 random port 的話,那麼可以…

Capybara.server_port = nil

 

2011/9/28 更新

記得把測試資料夾設定成 ./spec/requests/*_spec.rb,或是在每個測試項目加上「:type => :request」。如果資料夾不這麼命名,那就不會默認有「:type => :request」這個設置…成立一個新專案,要建置測試時出錯,找了一天才找到解法…

it 'xxxxxxxxxxxxx', :type => :request do
    # ......
end

 

參考資料

https://github.com/jnicklas/capybara/issues/483

2011年9月10日 星期六

Ruby on Rails multipart(上傳檔案) 讓 remote(ajax) 失效!

在 RoR 要 AJAX 來傳遞表單(form)非常的簡單,只需要把 form 的 remote 屬性設定成 true 就好。

<%= form_tag('/posts', :remote => true) %>
  # field here ...
<% end %>

 

而關於 AJAX event 的 handle,可以參考這篇

Rails 3 Remote Links and Forms: A Definitive Guide

 

 

但若要傳遞的是檔案就沒這麼簡單了,因為 form 的 multipart 屬性會讓 remote 失效!

<%= form_tag('/posts', :remote => true, :multipart => true) %>
  # field here ...
<% end %>

 

這並不是  RoR 的問題,而是 Javascript 本來就無法存取本機得資源,若要達成還是得利用 iframe 來讓瀏覽器幫忙將檔案送到 server 端而不重新讀取頁面,以 php 為例,你必須這樣做。

index.php

<form id="upload_form" method="post" enctype="multipart/form-data" action="upload.php">
    <input name="file" id="file" type="file"/>
    <input type="submit" name="action" value="Upload"/>
    <iframe id="upload_iframe" name="upload_iframe" style="width: 500px; height: 500px; border: 1px solid #000;"></iframe>
</form>
 
<script>
function init() {
    document.getElementById('upload_form').onsubmit=function() {
        document.getElementById('upload_form').target = 'upload_iframe';
    }
}
window.onload=init;
</script>

 

upload.php

<pre>
<?
    // 處理一般 upload 的程式碼放這,這邊只印出 $_FILES 的內容
    print_r($_FILES);
?>
</pre>
 
<script>
// 還是可以呼叫到前一個頁面的元素進行互動
alert(parent.document.getElementById('upload_form'));
</script>

 

在 RoR 世界裡,已經有人把他寫成套件了,或許安裝有點繁瑣,使用起來也不是那麼的順手,但基本上還是維持了 RoR 的一致性,可以參考看看底下這個 solution。(裡面已有安裝教學以及使用範例)

https://github.com/leppert/remotipart

2011年9月7日 星期三

Facebook API 循序圖

image
(圖的來源在 http://developers.facebook.com/docs/authentication/)

圖裡指的 APP 為 Facebook 中的 APP,通常以 WebSite 方式存在,以下皆以 WebSite 稱之。

步驟解說如下:

  1. 使用者來到 WebSite
  2. WebSite 提供一個連結至 Facebook 的「請求授權」頁面,連結的參數裡,帶有 WebSite 指定成功後跳轉的網址(通常指回自己身上),「請求授權」頁面會自動偵測使用者登入狀況來決定是否跳轉登入頁面。
  3. 「請求授權」成功後,Facebook 會通知 Browser 跳轉到步驟 2 指定的網址,並帶有 "code" 的參數。(這邊的 "code" 指的是「請求授權」成功的密鑰)
  4. WebSite 收到 "code" 之後,透過 "code" 連接到 Facebook 表示使用者已同意 WebSite 取得「access token」
  5. 取得「access token」之後,WebSite 便可透過「access token」直接對 Facebook 下達任何使用者授權的存取動作。

能請求的授權如下:
(來源在 http://developers.facebook.com/docs/reference/api/permissions/)

image
image
image
image

2011年9月6日 星期二

Ruby on Rails and Facebook API (koala)

 

我很訝異我無法在第一時間就 google 到 RoR 整合 Facebook API 的 solution。雖然不到千辛萬苦,但也是兜了一圈才找到這個 koala 套件。

https://github.com/arsduo/koala/wiki

 

如果要直接下載專案範例,那麼可以試試看

https://github.com/omeryavuz/yemek_koala

 

不知道是不是使用 VirtualBox 的關係,get_access_token 這個指令每次都回應我 auth_code 與 App id 不 match…但如果第二次訪問就可以正常取得 access_token,目前暫時用這個方式來解,還是得找時間實測看看實體機器。

2011年9月4日 星期日

Ruby on Rails 實戰聖經

image

 

連結如下:

Ruby on Rails 實戰聖經

 

看了這個網站一天,實在很佩服這位作者,讓我這個資質駑鈍的人可以很快的進入狀況,幾乎把每一個步驟有可能遇到的狀況與問題都描述的非常清楚。一般來說,高手常常會有盲點,他根本不知道新手究竟會遭遇到什麼問題,只能順順的帶過,但這作者真的非常巨細靡遺的講解,一定要好好推薦一下這位作者,以及即將出版的書!