タグ管理できるメモ帳を作る (1)
今回は関係ないですが、さくらで動かしている Rails に gateway.cgi を導入してみました。感激するほど爆速ですよっ!
さて初心者アプリにありがちなメモ帳です。メール投稿とか夢が広がりんぐです。今回はタグ管理できるメモ帳を作ってみたいと思います。スマートなやり方は知りませんが、多対多の関係になるので、メモのテーブルとタグのテーブル、そしてメモとタグのそれぞれの id を格納して関連付け行う、関連テーブルが必要です。最初に1対多じゃないの?と考えちゃってた辺り、慣れるまで複雑な所ですね。
今回みたいな単純な多対多関連を実現するには has_many とかじゃなくて has_and_belongs_to_many という長ったらしい名前で宣言します。略して habtm とか呼ばれてるらしいです。
まずはテーブルを作る
memo と tag のマイグレーションは scaffold で自動生成しました。いい加減 scaffold 離れした方がいいですね。関連テーブルのモデルは要らないので、マイグレーションファイルだけ作成します。関連テーブルにも命名規則があり、memos テーブルと tags テーブルの関連テーブルであれば memos_tags という名前になります。memos_tags に id は必要なく、memo_id (integer) カラムと tag_id (integer) カラムさえあれば良いです。
関連テーブルのマイグレーションファイルはこんな感じ。
class CreateMemosTags < ActiveRecord::Migration def self.up create_table(:memos_tags, :id => false) do |t| t.integer :memo_id t.integer :tag_id end end def self.down drop_table :memos_tags end end
そしてテーブル作成。
% script/generate scaffold memo title:string content:string tag:string % script/generate scaffold tag name:string % rake db:migrate
habtm の宣言
Memo と Tag それぞれのモデル内で habtm の宣言をします。
class Memo < ActiveRecord::Base has_and_belongs_to_many :memos end
Tag にも。
class Memo < ActiveRecord::Base has_and_belongs_to_many :memos end
挙動の確認
% script/console >> Tag.create( :name => 'test' ) >> kamo = Memo.create( :title => 'テストだよう', :tag => 'test' ) >> kamo.tags << Tag.find( :all, :conditions => ["name = ?", kamo.tag] )
これで関連付けたいアイテムの id が memos_tags テーブルに登録されます。1つのタグに複数のメモを関連付けて
% script/console >> tag = Tag.find(0) >> tag.memos.each do |r| ?> puts r.title ?> end
こんな感じで取り出せるよ!
次は登録画面。テーブル相関図をダイアリーのお絵描きツールや表組みで描けば分かり易かったですね。