default_scope と with_exclusive_scope

default_scopeを使うと論理削除を簡単に実現できる。たとえば論理削除したものは deleted_at に日時が入るという場合、

default_scope :conditions => ["deleted_at IS NOT NULL"]

とすると、論理削除されていないものだけが取得できる。

論理削除したものも取得したい場合は with_exclusive_scope を使う。

self.with_exclusive_scope do 
  self.all
end

とすると、全部が取得できる。

phpPgAdminをPHP5.3で動かそうとするといろいろとエラーが発生する

環境

PostgreSQLを使いたいのでmacportsphppgadminをインストールした。

sudo port install phppgadmin

postgresql84も一緒にインストールされたのでpostgresql84-serverをインストールする。

sudo port install postgresql84-server

で、インストーラーに言われたとおりに初期化

sudo mkdir -p /opt/local/var/db/postgresql84/defaultdb
sudo chown postgres:postgres /opt/local/var/db/postgresql84/defaultdb
sudo su postgres -c '/opt/local/lib/postgresql84/bin/initdb -D /opt/local/var/db/postgresql84/defaultdb'

phpPgAdminにアクセスしたらこんなエラーが出た。

Deprecated: Assigning the return value of new by reference is deprecated in /opt/local/www/phppgadmin/classes/Misc.php on line 342

エラー原因のソースを見てみる。
/opt/local/www/phppgadmin/classes/Misc.php

// Create a database wrapper class for easy manipulation of the
// connection.
include_once('./classes/database/' . $_type . '.php');
$data =& new $_type($_connection->conn);
$data->platform = $_connection->platform;

「&=」がいけないようなので「=」に修正

$data = new $_type($_connection->conn);

これでOK

なんでこんなエラーが発生したのか調べてみたところ、PHP5からオブジェクトは参照渡しがデフォルトになったが、PHP4時代の参照渡しである「&=」という記法も使えた。だが5.3からはこれがエラーになるようです。

やっとログイン画面が出たのでログインしてみると、こんどはこんなエラーが

Deprecated: Function split() is deprecated

splitも使えなくなってるらしい。grepでsplitを検索してみると以下で使われている。

  • ./libraries/adodb/adodb-datadict.inc.php
  • ./libraries/adodb/drivers/adodb-postgres64.inc.php

これらのsplitをexplodeに修正する。

これでやっとエラーが消えて使えるようになった。

ブロックを受け取れるヘルパー

入力フォームがたくさんあるシステムを作ってるとき、コピペしていくよりヘルパーにしちゃった方が楽だろうということで調べてみました。

たとえば単にdivで囲みたいっていうとき

<%= wrap_div("This is content given as parameter") %>
#=> <div>This is content given as parameter</div>

<% wrap_div do %>
  This is content given as block
<% end %>
#=> <div>This is content given as block</div>

のようにメソッドの引数でも渡せるしブロックでも渡せるようにしたい。
こういうときapplication_helper.rbとかに

def wrap_div(content = nil, &block)
  html = "<div>"
  html += content if content
  html += capture(&block) if block_given?
  html += "</div>"
  block_called_from_erb?(block) ? concat(html) : html
end

capture(&block) でブロックの実行結果を文字列で取得する
block_called_from_erb?(block) でブロックの有無を判別。ある場合は concat(html) でバッファに出力する。ない場合はそのままhtmlを返す。
これでできました。

#スーパーpreってすごい便利だけど行番号も出ればもっといいのになぁ

ダイアログなどのボタンをキーボードで移動する

Snow Leopardはデフォルトではダイアログなどのボタンをキーボードで移動できない。

これでは不便なのでTabキーで移動できるようにしたい。
[システム環境設定] -> [キーボード] の [キーボードショートカット]タブで[すべてのコントロール]を選択

これでTabで選択してSpaceで決定できるようになった。
Macスクリーンショット取るのも簡単でいいなぁ