Code Digest #1

by winson, 10 months ago.

我非常喜愛Revolution On Rails網站上一系列名為Code Digest的文章,內容主要由幾位程式員輪流貼上自己常用的、精巧的、方便的、簡潔的程式片段,並加以說明,我也來試著分享一下。

要問Revolution On Rails是什麼來頭?那就必須提一下Revolution Health。Revolution Health是前AOL創辦人Steve Case離開時代華納之後,另起爐灶,創辦的一家醫療、健康領域相關的網路公司。

這家網路公司採用Ruby On Rails技術,背後的開發團隊實力堅強,在Rails圈貢獻相當多的Plugin,例如這裡這裡、還有這裡

而他們所設立的部落格就是Revolution On Rails。

def post
  @page_title = 'Report your Bug'
  return unless request.post?
  @bug = Bug.new params[:bug]
  @bug.condition = 'New'
  @bug.user = current_user
  if @bug.save
    notice_stickie "Your Bug Reported!!" 
    redirect_to :action => 'show', :id => @bug
  else
    render :action => 'post'
  end
end

Scaffold最討人厭的莫過於在頁面新增、修改項目都要呼叫兩個action,例如新增要呼叫new, create;修改要呼叫edit, update,藉由判斷是否為post,可以把兩步合成一步。

def tag
  tag = params[:id]
  @page_title = 'Bugs tagged with ' + tag
  @tags = Bug.tags(:limit => 15, :order => 'count DESC')
  # Paginate an already-fetched result set (i.e. collection or array)
  # http://snippets.dzone.com/posts/show/389
  @bug_pages, @bugs = new_paginate Bug.find_tagged_with(tag), :page => params[:page]
  render :action => 'list'
end

在model寫一個新的tags method,可以直接取得by model的tag,就像使用finder一樣簡單;設計一個新的paginator,甚至可以by tag傳回model物件,並丟給paginator處理。

簡單9行,負責tag功能的controller就這樣完成,喔,還附帶分頁哩。view那裡修一下,連tag cloud都做起來。

class ApplicationController < ActionController::Base
  helper_method :logged_in?, :current_user, :current_user=, :admin_user?
有一些基本的判斷式,例如是否登入、取得目前使用者等等,會同時在controller及view使用,該怎麼寫可以達到這樣的目的?

寫成application controller可以給全部的controller使用,但不能給view使用;寫成helper可以給view使用,但不可以給controller使用。

當然你可以兩邊寫,不過,我通常寫在application controller,並宣告成helper_method,這樣一來他既是application controller,又是helper,可以同時在controller及view運用,而達到程式碼重複使用的目的。

def link_for_user(user)
  link_to user.name, :controller => 'user', :action => "show", :id => user
end
寫網頁程式最常遇到的處理就是user連結,例如一個user姓名、暱稱通常帶著連結到他個人頁面的網址。例如: 我只要傳user物件進去,就可以取得以下連結:
<a href="http://blog.pbg4.org/user/winson">winson</a>

善用link_to寫些簡單的邏輯並宣告為helper之後,在view只要下

link_for_user @user
就可以取得這一整串連結,既簡單又方便,同時也可以讓view乾淨又清爽。

# Table name: bugs

#  id               :integer(11)   not null, primary key
#  title            :string(50)    default("")
#  comment          :text          
#  created_at       :datetime      not null
#  commentable_id   :integer(11)   default(0), not null
#  commentable_type :string(15)    default(""), not null
#  user_id          :integer(11)   default(0)
#  commenter        :string(255)   

class Bug < ActiveRecord::Base
  acts_as_commentable
  acts_as_taggable
  alias :tags= :tag_with

  def name
    title
  end
end
我一直非常喜愛alias這個關鍵字,竟然可以在程式執行時期動態換掉一個method name,就像這裡只要簡單多加一行
alias :tags= :tag_with
就可以非常直覺地標示tag,例如:
@bug.tags = 'ladybug dragonfly butterfly'
臨時要更改資料庫欄位名稱,其實不需要去動資料庫,只要定義一個新的method即可,像這樣:
def name
  title
end

當我需要取得bug名稱,只要下

@bug.name
就可以得到資料庫裡面某一筆bug record的title。


  • Posted in Rails, Sugar, on Monday, August 13, 2007, at 07:16 PM.