2012年12月27日

railsでやっと理解したこと

小メモなんだけど。

railsのModelで、「article.comments[0].text」って書くとCommentsテーブルのarticle_idが現在のarticle_idを同じやつのtextカラムを取ってきてくれるじゃん。あれすごく便利なんだけど、railsが結構複雑な魔術を行使しているのでイマイチ自由に扱えなかった。
ついこないだやっと理解したので、それを書く。
  
モデル関連付けの基本

この手のものはモデルの関連って呼ぶらしいけど。

一つのArticleに複数のCommentがある場合、それぞれのモデルにはこういうふうに書く

Article.rb

has_many :comments

Comment.rb

belongs_to :article
するとartcle.comments[n]でn番目のコメントのレコードが取得できるし、comment.articleで親記事のレコードが取得できる。
ただ、これはいろんな設定値を省略しているので、自由に物事をやりたい場合ちょっと足りないんだ・・・
たとえば自分のレコード自身を参照する場合。articleの関連項目として別のarticleを複数指定できるようにするには?

Article.rbにhas_many :articlesなんて指定できるわけないし・・・

結論としては、別モデルreferを作って

has_one :to, class_name: "Article", foreign_key: "id", primary_key: "refering_id"

などとやればいいんだけど、これ、要は何をやっているのか。

has_one ホニャララ っていうメソッドは、ActiveRecordオブジェクトからメソッド呼び出しで別のテーブルの要素をとりだしてやるよということができるようにするものだ。言葉でつらつら書いてもわかりづらいと思うんで、具体的に説明すると・・・

Article.rbにhas_one :commentって書くと article.commentでこのArticleオブジェクトのidと一致するarticle_idを持つCommentオブジェクトを一つだけ取得してくれる
Article.rbにhas_many :commentsって書くと article.comments[0]、article.comments[1]などで、一致するarticle_idを持つCommentオブジェクトを取得してくれて、配列のインターフェースでアクセスしてくれる。

で、この:comment部分は後ろの引数に何も指定しないと同名のActiveRecord派生クラスしか指定できないのだけれど、上の例のようにclass_name:を指定すると、メソッドとクラス名を別々にできるんだ。

たとえばArticle.rbに has_one :comment, class_name: subarticle と書けばSubarticleクラスの、一致するarticle_idを持つものを取得できるし、呼び出しはarticle.commentのままでよい。

しかも、article_id部分を別のカラム名にしたいな〜〜、と思うのなら、primary_key: にソレを書けばいい。Article側の一致するidの部分のカラム名を変えたければforeign_key:に書けばいい。

という風に、オプション引数に色々入れれば、自由自在に連携方法を変えれるわけだ。いや〜、コレ理解するのにしばらくかかったわ〜

という俺用のメモでした。
タグ:Rails
posted by LoyalTouch at 07:37| Comment(0) | TrackBack(0) | Webプログラミング | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのトラックバックURL
http://blog.seesaa.jp/tb/310121285

この記事へのトラックバック