その他
    ホーム技術発信DoRubyActiveRecordのwhereの挙動メモ

    ActiveRecordのwhereの挙動メモ

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    ActiveRecordのwhereの挙動が同じだったり違ったりするのでメモ

    例として使うテーブル

    # 投稿
    class Post < ActiveRecord::Base
      has_many :comments
    end
    
    
    # コメント
    class Comment < ActiveRecord::Base
      belongs_to :post
    end
    

    1.whereにhash

    Post.where(title: 'タイトル').to_sql
    
    SELECT posts.* FROM posts WHERE posts.name = 'タイトル'  ORDER BY posts.id ASC
    

    default_scopeがつく

    2.whereにArray

    Post.where(['title = ?', 'タイトル']).to_sql
    
    SELECT posts.* FROM posts WHERE (name = 'タイトル')  ORDER BY posts.id ASC
    

    whereの条件にテーブル名がつかない。()がつく。

    3.Arrayの部分にテーブル名を入れる

    Post.where(['posts.title = ?', 'タイトル']).to_sql
    
    SELECT posts.* FROM posts WHERE (posts.name = 'タイトル')  ORDER BY posts.id ASC
    

    テーブル名がつく。()がつく。

    4.whereに空配列

    Post.where([]).to_sql
    
    SELECT posts.* FROM posts ORDER BY posts.id ASC
    

    where条件なし。全件取得。default_scopeがつく。

    5.whereに空配列

    Post.where([[]]).to_sql
    
    SELECT posts.* FROM posts WHERE () ORDER BY posts.id ASC
    

    全件取得。where ()がつく。

    6.whereにString

    Post.where("posts.title = 'タイトル'").to_sql
    
    SELECT posts.* FROM posts WHERE (posts.name = 'タイトル')  ORDER BY posts.id ASC
    

    Arrayのときとかわらない。

    7.whereに空文字

    Post.where('').to_sql
    
    SELECT posts.* FROM posts  ORDER BY posts.id ASC
    

    where条件なし。全件取得。default_scopeがつく。

    8.whereにtrue

    Post.where(true).to_sql
    
    RuntimeError: unsupported: TrueClass
    

    例外。

    9.whereに’true’

    Post.where('true').to_sql
    
    SELECT posts.* FROM posts WHERE (true)  ORDER BY posts.id ASC
    

    全件取得。

    10.whereに’false’

    Post.where('false').to_sql
    
    SELECT posts.* FROM posts WHERE (false)  ORDER BY posts.id ASC
    

    0件。

    11.joinしてwhereにhash

    Post.joins(:comments).where(title: 'タイトル', comments: {title: 'コメントのタイトル'}).to_sql
    
    SELECT posts.* FROM posts INNER JOIN comments ON comments.color_id = posts.id WHERE posts.title = 'タイトル' AND comments.title = 'コメントのタイトル'  ORDER BY posts.id ASC
    

    Postのdefault_scopeがつく。

    12.joinしてmerge

    Post.joins(:comments).where(title: 'タイトル').merge(Comment.where(title: 'コメントのタイトル')).to_sql
    
    SELECT posts.* FROM posts INNER JOIN comments ON comments.color_id = posts.id WHERE posts.title = 'タイトル' AND comments.title = 'コメントのタイトル'  ORDER BY posts.id ASC, comments.id ASC
    

    PostとCommentのdefault_scopeつく。