こんな感じの投稿システムがあったとします
sqlite> .tables
comments posts
む、sqlite3には mysql とかの describe 相当のコマンドが無いのだろうか。
とりあえずデータを突っ込んだ select で勘弁してね。
id|title|body|created_at|updated_at 1|title1|body|2010-09-25 05:55:18.912592|2010-09-25 05:55:18.912592 2|title2|body|2010-09-25 05:55:31.281979|2010-09-25 05:55:31.281979
いわゆるブログのエントリ的なものを想定して、titleとbodyっていうカラムがある。
そして、その各エントリにcommentが付く。
id|post_id|name|body|created_at|updated_at 1|1|hogehoge|comment1|2010-09-25 05:57:32.057127|2010-09-25 05:57:32.057127 2|1|hogehoge|comment2|2010-09-25 05:57:39.476946|2010-09-25 05:57:39.476946 3|1|hogehoge|comment3|2010-09-25 05:57:42.828758|2010-09-25 05:57:42.828758 4|2|unko|comment1|2010-09-25 05:57:53.740980|2010-09-25 05:57:53.740980 5|2|hogehoge|comment2|2010-09-25 05:58:03.020882|2010-09-25 05:58:03.020882
コメントには、対象となる post_id をもって紐付けさせる。
モデルでの関連付け
vim app/models/post.rb
has_manyを付ける
class Post < ActiveRecord::Base has_many :comments end
rails console で以下のように試すと、コメントデータも取れる。
Post.find(1).comments
=> [#, # , # ]
投稿メッセージにコメント数をつけたい
いわゆる commnet(1) とかをつけたい場合ね。
上記が試せていれば、
Post.find(1).comments.length
とかで取れる訳だけど、json などで渡すときに不都合ですよね。
まず、モデルにメソッドを定義する
一応、何回も呼ばれたときの為にキャッシュしておく。
class Post < ActiveRecord::Base has_many :comments def comment_count @comment_count ||= comments.length end end
rails console で確認してみよう。
ruby-1.9.2-head > Post.find(1).comment_count
=> 3
おお、できてる。
to_json(to_xml)でメソッド呼び出しをする
:methods オプションで呼べる。
ruby-1.9.2-head > puts post.to_json(:methods => :comment_count)
{"post":{"body":"body","created_at":"2010-09-25T05:55:18Z","id":1,"title":"title1","updated_at":"2010-09-25T05:55:18Z","comment_count":3}}
整形するとこんな感じで、最後に comment_count っていうのが付く
{ post: { body: body (string) ,created_at: 2010-09-25T05:55:18Z (string) ,id: 1 (number) ,title: title1 (string) ,updated_at: 2010-09-25T05:55:18Z (string) ,comment_count: 3 (number) } }
整形は例のごとく JSON整形 を使った。
ちなみに、:methods で複数のメソッドを呼びたい場合は [:method名, :method名]のような感じで配列にすると良い。
これで
データを弄り回さずに出力用の形式に整形できますね。
enjoy!