ユーザ用ツール

サイト用ツール


rails:active_record

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
rails:active_record [2024/01/10 06:15] nullponrails:active_record [2024/01/10 14:30] (現在) nullpon
行 71: 行 71:
  
 ===== nemed_scope ===== ===== nemed_scope =====
-(rails 2.1 or later) 
  
 よくある検索条件をメソッド化できる。 よくある検索条件をメソッド化できる。
 <code rubyt> <code rubyt>
 User < ActiveRecord::Base User < ActiveRecord::Base
-  named_scope :active, :conditions => { "state" => "active" } +  scope :active, where(state: "active") 
-  named_scope :teenager, :conditions => {"age=13..19 } +  scope :teenager, where("age >= 13 and age <= 19") 
-  named_scope :male :condtions => {"sex" => } +  scope :male, where(gender: 1) 
-  named_scope :age, lambda{ |x{ :conditions => ["age = ?", x] }}+  scope :age, -> x { where(age: x}
 end end
 </code> </code>
行 147: 行 146:
  
 検索時は 検索時は
-  LimitedItem.find(:all+  LimitedItem.all 
 とすれば、 とすれば、
   select * from items where type = "LimitedItem";   select * from items where type = "LimitedItem";
行 160: 行 159:
 class ItemsController class ItemsController
   def index   def index
-    @items = Item.find(:all)+    @items = Item.all
   end   end
 end end
行 208: 行 207:
  
 ===== テーブル結合 ===== ===== テーブル結合 =====
 +
 +==== eager_loadとjoin ====
  
 eager loading(多対一リレーションなデータで、多を検索したときに一のデータもjoinして取っておく事)する eager loading(多対一リレーションなデータで、多を検索したときに一のデータもjoinして取っておく事)する
行 221: 行 222:
  
 books.each { |book| puts book.author.name } books.each { |book| puts book.author.name }
 +</code>
  
 +<code sql>
 +select .. from books where (title like 'あ%');
 +select .. from authors where id = 1; -- booksの取得件数だけSQLがauthorを取得するSQLが実行されてしまう
 +select .. from authors where id = 2;
 +select .. from authors where id = 5;
 +.
 +.
 +.
 +</code>
  
 +
 +<code ruby>
 # authorも同時に取得(left outer joinを使用) # authorも同時に取得(left outer joinを使用)
 books = Book books = Book
行 232: 行 245:
  
 <code sql> <code sql>
-select .. from books left outer join authors on books.author_id = authors.id where (books.title like 'あ%')+select books.*, authors.from books  
 +  left outer join authors on books.author_id = authors.id where (books.title like 'あ%');
 </code> </code>
  
- +left outer joinのため、 author が nil になる可能性があるので注意inner joinで結合したい場合はjoinsを併用する
-関連テーブルの内容はleft outer joinで取得される。よって author が nil になる可能性がある点に注意 +
- +
-inner joinで結合したい場合はjoinsを併用する+
  
 <code ruby> <code ruby>
行 251: 行 262:
  
 <code sql> <code sql>
-select .. from books inner join authors on books.author_id = authors.id where (books.title like 'あ%')+select books.*, authors.from books  
 +  inner join authors on books.author_id = authors.id where (books.title like 'あ%')
 </code> </code>
  
  
- +joinsを単体で使用するSQL発行時にauthorsテーブルをinner joinするがauthorデータ取得は行わない。検索条件にauthorを使いたいがauthorのデータは不要な場合に使用する
-joinsを単体で使用する場合、SQL発行時にauthorsテーブルをinner joinするがauthorデータ取得ない。これは検索条件にauthorを使いたいがauthorのデータは不要な場合に使用する+
  
 <code ruby> <code ruby>
行 266: 行 277:
  
 <code sql> <code sql>
-select .from books inner join authors on books.author_id = authors.id where (author.name like 'あ%')+select books.from books  
 +  inner join authors on books.author_id = authors.id where (author.name like 'あ%')
 </code> </code>
  
  
-preloadはjoinせず、2つのSQLを発行する。JOINが重い場合はこちらが有用+==== preload ==== 
 + 
 +preloadはjoinせず、2つのSQLを発行して関連データを取得する。
  
 <code ruby> <code ruby>
行 282: 行 296:
  
 <code sql> <code sql>
-select .from books where (books,title like 'あ%'); +select books.from books where (books,title like 'あ%'); 
-select .from authors where authors.id in (1,2,5); -- 最初のSQLで取得されたレコードのauthor_idで検索+select authors.from authors where authors.id in (1,2,5,...); -- 最初のSQLで取得されたレコードのauthor_idで検索
 </code> </code>
  
 +
 +==== includes ====
 +
 +includesは特殊で、通常はpreloadと同じ動きだが、結合テーブル側を検索条件に含めるとeager_loadに変わる
 +
 +
 +<code ruby>
 +books = Book
 +        .where("books,title LIKE ?", "あ%")
 +        .includes(:author)
 +
 +books.each { |book| puts book.author.name }
 +</code>
 +
 +<code sql>
 +select books.* from books where (books,title like 'あ%');
 +select authors.* from authors where authors.id in (1,2,5,...);
 +</code>
 +
 +author側に条件があるとjoinする(ただしオブジェクト形式での条件指定しかできない)
 +
 +<code ruby>
 +books = Book
 +        .where("books,title LIKE ?", "あ%")
 +        .includes(:author)
 +        .where(author: {birth_year: 1987})
 +
 +books.each { |book| puts book.author.name }
 +</code>
 +
 +<code sql>
 +select books.*, authors.* from books 
 +  left outer join authors on books.author_id = authors.id 
 +  where books.title LIKE 'あ%' and authors.birth_year = 1987;
 +</code>
  
rails/active_record.1704867305.txt.gz · 最終更新: 2024/01/10 06:15 by nullpon