2010年03月17日

Rails include joins

includeとjoins、Railsにしたがって大して細かいことをしない場合なんかは、includeで細かく指定したいときなんかはjoinsなんて風に自分は考えています。

なにそれ?


include・joinsなんだそれ?という方に、
これは、Railsのfind文の中に書くもので、
Hoge.find(:all, :include => 'boges')
Hoge.find(:all, :joins => 'LEFT JOIN boges ON hoges.id = boges.hoges_id')

上記のようにして、HogeテーブルとBogeテーブルを結合させています。

include


includeを使用する場合は、modelにてどのテーブルのどこを見るという下記のような指定が必要です。
$vi hoges.rb
class Hoge < ActionRecord::Base
 has_many :boges
end

$vi boges.rb
class Boges < ActonRecord::Base
 belongs_to :hoge
end

上記の例だと、hoge : boge = 1 : n(多)となっており、
カラム名を指定しない場合、HogeテーブルのidとBogeテーブルのhoge_idを自動で指定してくれます。
has_many :boges, :foreign_key => 'mo_id'

上記の様にすると、HoegテーブルのidとBogeテーブルのmo_idを見るようになります。

Hoge.find(:all, :include => 'boges')
//bogesという名前はhoges.rbのbogesと同じ名前


joins


これはSLQ(PostgreSQL)を書く内容を書くだけです。
特にこれといって書くことはないので、
LEFT JOINとRIGHT JOINの違いについて書いておきます。

LEFT JOIN


table1
----------
id | name
----------
1 | test1
2 | test2

table2
-----------
id | table1_id | name2
----------------------
1 |     1 | mo1
2 |     3 | mo2

Hoge.find(:all, :joins => 'LEFT JOIN table2 ON table1.id = table2.table1_id')

上記の場合の結果は、
table3
-------
id | name | id | table1_id | name
1 | test | 1 | 1 | mo1
2 | test2| 2 | |
つまり、table1が優先されるため、table2のtable1_id=3はtable1に存在しないので無視されます。

RIGHT JOIN


RIGHTの場合は、table2が優先されます。
table3
----------
id | name | id | table1_id | name
1 | test | 1 | 1 | mo1
| | 2 | 3 | mo2
こんな感じになります。

includeとjoinsの違い


何が違うか?
自分が思うところの違いは2点です。
1、joinsは、モデルに宣言不要
2、joinsは、selectで指定が可能。
ほかのも速度関連で違いがあると思いますけど、
まぁ何かしらincludeで不備がないかぎりincludeを普通つかいますかね。
ほかの言語のDBとかの連携だとidの決まりなんかがぜんぜん違うんでjoinsのほうがよかったりします。
posted by RicK at 16:36| Comment(0) | TrackBack(0) | 日記