顯示具有 Ruby on Rails 標籤的文章。 顯示所有文章
顯示具有 Ruby on Rails 標籤的文章。 顯示所有文章

2011年9月27日 星期二

Ruby on Rails 發佈 Twitter 消息

image

圖片來源:https://dev.twitter.com/

 

流程大綱

要在 Twitter 發佈消息,要做幾件事情:

  1. 註冊一個 Twitter 帳號
  2. 用 Twitter 帳號申請 Twitter APP
  3. 將 Twitter APP 權限調整成 「Read and Write」
  4. 在 Ruby on Rails 透過 Twitter OAuth 認證機制取得 access_token
  5. 利用 Ruby on Rails 用 access_token 呼叫 Twitter API 進行發佈

 

參考資訊

https://github.com/oauth/oauth-ruby

https://github.com/twitter4r/twitter4r-core

http://twitter4r.rubyforge.org/

 

流程說明,直接從「用 Twitter 帳號申請 Twitter APP」開始

登入你的 Twitter ,在右下方找到「開發人員」

image

 

一樣在右下方,點擊「Create an app」

image

 

填寫 APP 所需資訊,在這邊 Web Site / Callback URL 的 host:port 是填寫你自己的網站位址(測試用的話,填 127.0.0.1:3000 也可以)

PS:"myapp" 若跟人家衝突到,就自己亂 key 一個名字吧,實際上我是 key “myapp1234”

image

 

填好之後,打勾按下同意

image

 

按下 Settings

image

 

將 Access 的 permission 更改為 Read and Write 按下送出

image

 

image

 

回到 Details

image

 

把 Key 跟 Secret 記下來

image

 

接著產生一個 RoR 的專案

SNAGHTML240def4

 

在 GemFile 裡加上這兩行

image

 

下達 bundle install

SNAGHTML242353e

 

接著下達 rails g controller twitter

SNAGHTML243dd11

 

打開 controller twitter_controller.rb 貼上以下程式碼

image 

class TwitterController < ApplicationController
  def consumer
    consumer = OAuth::Consumer.new('你剛剛申請到的 Key ', '你剛剛申請到的 Secret', {
      :site => 'https://api.twitter.com',
      :authorize_path => '/oauth/authorize'
    })
    return consumer
  end
  
  def login
    request_token = consumer.get_request_token(:oauth_callback => File.join(request.protocol + request.host_with_port, 'twitter/callback'))
    session[:request_token] = request_token.token
    session[:request_token_secret] = request_token.secret
    redirect_to request_token.authorize_url
  end
  
  def callback
    request_token = OAuth::RequestToken.new(consumer, session[:request_token], session[:request_token_secret])
    access_token = request_token.get_access_token(:oauth_verifier => params[:oauth_verifier])
    client = Twitter::Client.new(:oauth_access => {
      :key => access_token.params[:oauth_token], :secret => access_token.params[:oauth_token_secret]
    })
    client.status(:post, '你要發佈的消息')
    render :text => access_token.params
  end
end

 

到 config/routes.rb 把最下面一行註解拿掉

image

 

接著打開 rails server

SNAGHTML24df66a

 

打開瀏覽器輸入底下網址

image

 

授權應用程式

image

 

稍等一下會跳轉到 callback 頁面

image

 

此時到 Twitter 上看,就可以看到消息成功發佈了!

image

 

 

PS:若你要發佈的消息為中文,記得把檔案編碼改為 utf-8 並在檔案上方加入 「#encoding: utf-8」 喔!

image

image

2011年9月16日 星期五

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月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 實戰聖經

 

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