2011年1月24日月曜日

Rails3 複数のカラムでユニーク

ツリー構造のカテゴリで

例えば、カテゴリ名を重複させたくないというのは簡単だけど、親子関係を持つカテゴリで親同士内、子同士内、孫同士内ででだけ名前の重複をさせたくないという時にRailsでどう書くのか。

マイグレーション

def self.up
  create_table :categories do |t|
  ...
  end
  add_index :categories, [:parent_id, :name], :unique => true
end

モデルのバリデーション

class Category < ActiveRecord::Base
  acts_as_tree
  validates_uniqueness_of :name, :scope => :parent_id
end

MySQL 5.5.8をDebian 5 lenny にインストールしてみた

ソースからコンパイル

ちなみにsakura VPSに入れたのですが、もともとMySQLが入っていたっぽかったので、whereis mysqlで出て来たものはディレクトリごとrm -rfしましたw

apt-get install libncursesw5-dev cmake
wget http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.8.tar.gz/
tar zxf mysql-5.5.8.tar.gz
cd mysql-5.5.8
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql/5.5.8 -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci
make
make install

パスを通す
vim ~/.bashrc
export PATH="${PATH}:/usr/local/mysql/5.5.8/bin"
保存

source ~/.bashrc
# あ、~/じゃなくてちゃんとシステム全体に反映されるのに書いた方がいいな...と今思った


groupadd mysql
useradd -g mysql mysql

chown -R mysql /usr/local/mysql/
cd /usr/local/mysql/5.5.8/
script/mysql_install_db
# 新たにファイルが作成されるのでアクセス権を再度設定
chown -R mysql /usr/local/mysql
mysqld_safe --user=mysql &
mysql_secure_installation

vim /etc/ld.so.conf.d/mysql.conf
/usr/local/mysql/5.5.8/lib
保存

ldconfig

# ついでに自動起動も
install -o root -g root -m 755 /usr/local/mysql/5.5.8/support-files/mysql.server /etc/init.d/mysql
chkconfig --add mysql

あなたも漢(オトコ)のコンピュータ道: MySQL 5.5新機能徹底解説を読んで「うぉぉおおお!!」となって、MySQL5.5をサーバにインストールするといいよ!

2011年1月16日日曜日

Macでgit completion

コマンドとブランチをtab補完しよう

Gitはコマンドが多い! alias作っとけよって話かもしれませんが、aliasは補完じゃなくてpush origin master とかを短いオレオレコマンドにしちゃおうというエイリアスですから用途が違う訳です。今回はブランチまで補完できるようにしちゃうよ!

~/.profileに書き込む

git-comletionのスクリプトが必要ですのでmdfindでどこにあるか探しましょうw 以下はgit-osx-installerでインストールしたおいらの環境での例

if [ -f /usr/local/git/contrib/completion/git-completion.bash ]; then
  source /usr/local/git/contrib/completion/git-completion.bash
  PS1='[\W$(__git_ps1 " (%s)")]\$ '
  export PROMPT_COMMAND='echo -ne "\033]0;${PWD/#$HOME/~}\007"'
fi

source ~/profile としておけばOKです。

使い方

  • git co<TAB> とするとcommit configが出ます さらにmを押してタブキーを押すとgit commitになります
  • レポジトリで git push <TAB> とするとブランチのリストが出ます 便利!

2011年1月15日土曜日

Rails3でPHPのnumber_format関数はnumber_with_delimiter

ActionView::Helpers::NumberHelperに定義されている

とくにincludeすることなく使えるのでビューに以下のように書けばOK!integerでもstringでもOK!

# pruduct.price = 1000
<%= number_with_delimiter product.price %>
# 1,000が表示される

価格はnumber_to_currency

ロケールとcurrency format unitがja.ymlで設定されている場合は、number_to_currencyで3桁ごとにコンマがふられ、最後にja.ymlのunitが表示される。

# pruduct.price = 1000
<%= number_to_currency product.price %>
# 1,000円 と表示される

2011年1月14日金曜日

MacでMySQL5.5を入れたらmysql2使ってたからRails3君が動かなくなってん

こんなエラーが

Referenced from: ./rvm/gems/ruby-1.9.2-p0/gems/mysql2-0.2.3/lib/mysql2/mysql2.bundle
Reason: image not found - .rvm/gems/ruby-1.9.2-p0/gems/mysql2-0.2.3/lib/mysql2/mysql2.bundle

とか gem install mysql2で

Enclosing class/module 'mMysql2' for class Client not known

などなど

install_name_toolで解決

上記のエラーはmysql2-0.2.3になってますが、途中で最新版に上げたので、以下のはmysql2-0.2.6の解決方法です。というかパスを返ればmysql2-0.2.3でもきちんと動きます。

sudo install_name_tool -change libmysqlclient.16.dylib \
/usr/local/mysql/lib/libmysqlclient.16.dylib \ 
~/.rvm/gems/ruby-1.9.2-p0/gems/mysql2-0.2.6/lib/mysql2/mysql2.bundle 

gem install mysql2のオプション

これは関係があるか分からないけど、 --with-mysql-dirをしといた方がいいかも

gem install mysql2 -- --with-mysql-dir=/usr/local/mysql

動くようになりました

ワイ!MySQLのUTF-8は4バイト以上のものは5.5からサポートされたらしいので、難しい漢字(日本人の人名漢字も含まれる><)サーバ側も近々アップグレードしないと...

2011年1月13日木曜日

Rails3でキャッシュを解放する時にSweepを使ってオブザーバーパターン!!

Sweep!

キャッシュ解放の命令をコントローラに直接書きたくないんだ!

# app/top_controller.rb
caches_page :index

# app/posts_controller.rb
cache_sweeper :post_sweeper

# app/sweepers/post_sweeper.rb
class PostSweeper < ActionController::Caching::Sweeper
  observe Post

  def after_create(post)
    expire_public_page
  end

  def after_update(post)
    expire_public_page
  end

  def after_destroy(post)
    expire_public_page
  end

  private
  def expire_public_page
    expire_page :controller => 'top', :action => 'index'
  end
end

上記の用に、ActiveRecordを監視して、キャッシュをお掃除するという感じです。コントローラのcreate/update/destroyに埋め込むより、素早くどこでキャッシュを解放しているかが分かるのでいいですね。

キャッシュがpublic/index.htmlだったりする件について

キャッシュがうまく消えなかったあの頃、ビューファイルをいじっても反映されず、development.rbのキャッシュを無効にする設定をやっても反映されず... どうしたんだぁヘヘイベイベー!と清志郎の歌を歌いながらgit statusしてみたら、public/index.htmlが復活していた!

これはパフォーマンス上はいいと思うんだけど、認証が前提のグループウェアとかの場合って、静的ファイルになっちゃうと困る部分がありますよね。ここら辺はどうするんだろう。きっとうまいやり方があるんだろうな。そのうち必要になったら調べよう

追記: Railsのキャッシュの種類

調べました。Railsには、

  • ページキャッシュ
  • アクションキャッシュ
  • フラグメントキャッシュ
の3タイプのキャッシュがあって、今回のページキャッシュは静的ファイルを生成するものでした。残りの2つのキャッシュについては近い将来絶対に利用すると思うので、その時にまとめられたらいいなと思ってます。

2011年1月11日火曜日

Rails3のRoutesでnamespaceとform_forに挑む

Adminルーティング的な事をしたかったのよっ!

例えば、ブログもそうだけど、一般の人がなんでもかんでもデータを操作できるのはまずいから、管理者用のページを用意するけど、意外と管理者用のページが多いと、コントローラを管理者用と一般用とに分けておいた方がいいんじゃね?ってなりますよね?この考え方が間違ってるとなれば、もうここから先は全くの無駄になってしまうんだけど、とりあえずやってみてうまく動いたから書いておきます。意外と躓くところなんじゃないだろうか

config/routes.rb

namespace 'admin' do
  resources :posts
end

admin/posts_controller.rb

#new, edit, create, updateなどで
@post = Post.new #など Postのインスタンスを入れる (AdminPostではない)

posts/_form.html.erb

<%= form_for [:admin, @post] do |f| %>

たったこれだけ。まじ簡単。app/controllers/adminの中のコントローラはログイン画面以外を除いてあとは全部認証が通ってないとアクセスできないことにしておけばいいからアクセス権限周りのことが把握しやすい構成になると思います。namespaceじゃなくてscopeでもいいんじゃ?とかあるかもしれないけど、その辺の判断はまだできてないから今後の課題です。勉強中!

2011年1月7日金曜日

Rails3で404 Not Foundを返してTemplate Missingエラーも出さない方法

何も描画したくない!

render nothing: true

404 Not Foundを返したい

render status: 404

これを合わせると

render status: 404, nothing: true

簡単。びっくり。