對抗垃圾信!請您點這裡:

我的E-mail:
我的Skype:My status

2008年7月3日

HTTP Response 500!?

剛剛在解決一個小Bug
用瀏覽器瀏覽某個會丟301的網站時,在Ruby或Telnet都會丟500回來
什麼鬼.. 怎麼會這樣?

其實這是因為沒有User-Agent的關係啦
有些Web Server可能會Reject一些Header中沒有User-Agent的Request
所以這時候只要在丟request時加上User-Agent這個Header即可
原本的原始碼:

response = Net::HTTP.get_response(URI.parse(uri_str))
改成:
uri = URI.parse(uri_str)
http = Net::HTTP.new(uri.host)
response = http.send_request('GET', uri.request_uri, {"User-Agent" => "Mozilla/5.0"})
這樣一來不管是301、302,還是最該死的404都沒問題啦XD

(( 因為這篇是工作上的心得,所以只好擺在Rails啦XD

2008年6月24日

修改error_messages_for,讓表單錯誤資訊中文化更完整

今天摸會了Git,就順便應用上了
error_messages_for大家都用過,也都知道這個不管再怎樣中文化,欄位名稱一樣都會出現給你看!
這真的是令人又愛(英語體系者愛)又恨(非英語體系者恨)的功能啊..
沒辦法,只好自己動手了...
我剛剛發了Git pull給Rails團隊,他們接受不接受我不知道,所以在這邊教大家如何自己搞定這一切
首先,先打開Rails這部份的原始碼
假設我Ruby安裝在C:\
所以路徑就是:C:\ruby\lib\ruby\gems\1.8\gems\actionpack-2.1.0\lib\action_view\helpers\active_record_helper.rb
接 著,跳到error_messages_for那段程式碼,在options = params.extract_options!.symbolize_keys底下加入:fields = options[:fields].nil? ? {} : options[:fields]
然後把error_messages = objects.sum {|object| object.errors.full_messages.map {|msg| content_tag(:li, msg) } }.join這行註解,改為:

error_messages = objects.sum {|object| object.errors.full_messages.map {|msg|
unless fields[msg.split(" ")[0].downcase.to_sym].nil?
msg = msg.split(" ")
field_name = msg.shift.downcase!
msg = msg.reverse.push(fields[field_name.to_sym]).reverse.join(" ")
end
content_tag(:li, msg)
} }.join
存檔離開,然後這樣用:
error_messages_for(:project, :fields => {:name => "專案名稱", :summary => "專案摘要"})
而content_tag產生出來的就會是
  • 專案名稱 can't be blank

  • 專案摘要 can't be blank

  • 很簡單吧:P?
    注意,只能夠傳小寫的symbol進去
    沒辦法,我功力太差了=_=|||
    可以參考這邊:http://github.com/cfc/rails/commit/9e38903fd10a2de9ae9c2ca53623469f3575b43c
    有任何問題歡迎提出,也可以在github上commit給我
    多謝多謝:P

    2008年4月17日

    Yahoo-LifeType-API (Yahoo!奇摩生活+ Ruby API)

    今天剛看到生活+釋出API(其實早就釋出了,API網址:http://tw.developer.yahoo.com/lifestyle_api.html)後,就開始把NetBeans打開來寫程式了XD
    現在RubyForge的專案還沒開,倒是GoogleCode的已經開了(網址:http://code.google.com/p/yahoo-lifetype-api/)
    程式是BSD授權,忘記怎樣包裝Gem檔,等到哪天想起來再包XD
    程式使用範例(列出生活+的分類):

    #!/usr/bin/env ruby
    APPID = "NhYX9XjV34FPxdq7zD8T7wwc4QGI5VWu_48NHh03zbPYUfPpcWrpZzhcVDKFQsH9dQ--"
    require 'lifetype'
    require 'rexml/document'
    include REXML

    puts "獲取生活+類別中... 請稍後"
    doc = Document.new(LifeType::Class.new(APPID).listClasses)
    puts "獲取類別結束"
    puts "類別總數: " + doc.get_elements("//rsp/ClassList")[0].attribute("count").to_s
    puts "列出類別中... 請稍後"
    doc.elements.each("//rsp/ClassList/Class") do |ele|
    puts "ID: #{ele.attributes["id"]} -- #{ele.get_elements("Title")[0].text}"
    end
    puts "列出類別結束"
    很簡單的就可以使用了,還有doc喔!
    有Bug可以丟到GoogleCode的Issues或者丟到我信箱內
    謝謝^^


    2007年9月13日

    偵測DNS是否還活著.. 用Ruby

    有鑒於某台主機的DNS常常掛掉.. 所以就寫了這個小程式..

    while true
      `ps aux | grep named`.split("\n").each{|line|
        user, pid, cpu, mem, vsz, rss, tty, stat, start, time, *command = line.split("\s")
        flag = true if command[0] == "/usr/sbin/named"
        `/etc/init.d/named start` unless flag
      }
      sleep 300
    end


    2007年9月10日

    線上Ruby Regular Expression Editor

    Ruby/Rails寫到一半.. 忽然需要用到RegExp來驗證某個東西(Ex: E-mail),卻臨時找不到工具可以測試自己寫的RegExp是否正確該怎辦?
    沒關係!這邊有個網站:http://www.rubular.com/
    這個網站可以讓您線上測試RegExp是否正確唷:)
    可以試試看!

    資料來源:China on Rails http://chinaonrails.com/topic/view/723/1.html

    2007年7月30日

    WxWidgets初體驗

    最近無聊想寫點小程式.. 可是不想用Visual Basic寫,用Ruby + GUI Toolkit寫
    可是該選哪套GUI Toolkit? 說真的.. GTK+好難用喔ˊˋ.. Qt完完全全不想用
    WindowsAPI? 那我乾脆用VB就好了=..=
    選來選去看來看去.. 乾脆就看了godfat的建議,去玩wxWidgets
    wxWidgets在Ruby上的binding叫做WxRuby,我們先來做準備吧。
    首先,我們要安裝wxWidgets跟WxRuby
    連線到http://www.wxwidgets.org/下載wxWidgets
    接著打開命令提示字元,輸入gem i wxruby -y
    一切搞定後,就可以開始先來寫個"哈囉握的"
    開啟irb,輸入以下程式碼

    require 'rubygems'
    require 'wx'
    include Wx # => 我比較懶XD

    class HelloWorld <> on_init override
    helloframe = Frame.new(nil, -1, "HelloWorld")
    StaticText.new(helloframe, -1, "Wa ha ha")
    helloframe.show
    end
    end

    HelloWorld.new.main_loop

    在wxWidgets中,每個視窗都是一個Frame,而StaticText則是Label(在VB中就叫做Label,SWT我不知道XD)
    Okok.. 可以動對不對? 不能動那就.. (( 當作沒看到

    繼續...
    或許各位會認為很奇怪,為什麼要自己慢慢寫.. 不要用視覺化的開發工具呢?
    現在來跟各位介紹,在GTK中有所謂的Glade,那在wxWidgets呢?當然有wxGlade!
    如果不喜歡wxGlade,這邊也有列表:[網址太長請點我]
    在wxWidgets中,支援一種叫做XRC(XML Resource)的格式檔案,很多視覺化工具,如wxGlade都支援輸出這種檔案。
    這種檔案的好處是不管是哪種開發工具或者程式語言,都可以藉由這個XRC檔案來產生一樣的介面。
    各位可以到http://wxglade.sourceforge.net/下載wxGlade,安裝後就可以開始拖拉了。
    弄好一個介面後,我們選擇產生XRC檔案。
    接著在同個目錄下,新增一個.rb檔案。
    假設我們有一個Frame與一個Button
    Frame: MainFrame
    Button: btnButton
    程式碼如下

    require 'rubygems'
    require 'wx'
    include Wx

    class MainFrame < btn =" find_window_by_id(xrcid('btnButton'))" xml =" XmlResource.get" xrc_file =" File.join(File.dirname(__FILE__)," main =" MainFrame.new">
    OK,大致上就這樣囉..

    2007年6月29日

    Rails中實做下拉式選單

    太久沒有寫文章了.. 最近接到一個案子.. 剛好讓我重溫Select的使用方法..
    嗯.. 結果卡在multiple,不知道是我太想睡還是怎樣.. 居然傻了..
    跑去#rubyonrails問,一位名為carpet_the_walls的網友給了我他寫的文章,網址是:
    http://shiningthrough.co.uk/Select+helper+methods+in+Ruby+on+Rails
    在此先謝謝carpet_the_walls (Thank you, carpet_the_walls)

    來做個Memo.. 不然又忘記了..
    在Rails中真的有一堆Select helper可以用.. 不只carpet_the_walls混淆,連我也模糊不清!
    常見的有三個..
    select, select_tag, collection_select(其餘的什麼select_date那些不談)
    我們先來看看一個基本的下拉式選單骨架

    <select name="selection">
      <option value="1">Opt1</option>
      <option value="2">Opt2</option>
    </select>
    在一個下拉式選單中,有一些是必備的資訊,像是"name"、"value"與"text"三個,在回傳資訊給Server時,"name"將是接收資訊用的,而"value"會傳回被選的值,而"text"則是使用者會看到的字,依上面的例子來講,Opt1、Opt2這兩個就是屬於"text"

    開始講講那三種Select helper

    select:
      select(object, method, choices, options = {}, html_options = {})
      在ActionView::Helpers::FormOptionsHelper中定義

    • object是一個實體化變數,這裡很明顯的就是要擺上model物件嘛!
    • method則是object的一個屬性,也是資料表中的對應欄位
    • choices就是要被選的選項,可以是陣列或者是雜湊(Hash)
    • options與html_options則是一些選項
    在這邊來舉個例子吧
    <%= select("project", "teacher_id", @teachers.collect{|t| [t.name, t.id]}, { :include_blank => false }) %>
    <%= select("project", "student_id", {"CFC" => '1', "EF" => '2'}) %>
    第一個例子中,@teachers在Controller是這樣的
    @teachers = Teacher.find(:all, :select => 'id, name')

    select_tag:
      select_tag(name, option_tags = nil, options = {})
      在ActionView::Helpers::FormTagHelper中定義

    如果你很喜歡手動打option的話.. 那用select_tag準沒錯啦!
    在select_tag中,name將會是params所接收值所用的鍵
    直接看範例
    <%= select_tag 'user', "<option>CFC</option>" %>
    這時在Controller中將會用params[:user]來接收傳過來的值
    但是select_tag也可以搭配options_for_select或者options_from_collection_for_select一起使用.. 來看一個範例吧
    <%= select_tag('sid[]', options_from_collection_for_select(@students, 'id', 'name'), :multiple => true)%>
    因為加上了:multiple,所以可以接受多值選擇,這時在Controller接收到的sid將會是一個陣列,這也是我所卡住的地方.. (( 真丟臉

    collection_select:
      collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
      在ActionView::Helpers::FormOptionsHelper中定義

    如果資料來源是從資料庫來的話,可以使用這個來做下拉式選單。
    這個Object不用我說,就是你的model
    method呢?當然就是欄位啦
    其實嚴格說起來,這只是select+options_from_collection_for_select的組合啦!
    範例:
    <%= collection_select(:payment, :id, @payments, :id, :name, options ={:prompt => "-Select a continent"}, :class =>"payment") %>

    再次謝謝原作者carpet_the_walls:)