Rails(Active Record)でのモデルの作成、検索、更新、削除でよく使うメソッドをまとめました。
動作確認
- Rails 4.1
目次
※モデルの検証や関連については、こちらへ
※モデルの挙動がわかりづらい場合は、rails c -s
で、サンドボックスモードで下記のコマンドを実行してみてください。
1. モデルの生成と保存
属性を設定してモデルオブジェクトを生成する(newメソッド)
new
メソッドにカラム名と値ををハッシュで渡すことで値を設定してモデルオブジェクトを生成することができる。
user = User.new(name: "田中", email: "tanaka@test.co.jp")
ハッシュで値を設定する
モデルオブジェクトのattributes
属性にカラム名と値をハッシュで渡すことで、モデルオブジェクトに一気に値を設定することができる。
user = User.new user.attributes = {name: "田中", email: "tanaka@test.co.jp"}
モデルを保存する
save
メソッドで保存する。
バリデーションエラーが発生した場合は falseが返る。さらに、errors.full_messages
にエラーメッセージが設定される
user.save # => true (ユーザーがDBに保存された) user.save # => false (バリデーションエラーが発生したため、DBに保存されなかった) user.errors.full_messages # => ["Name can't be blank", "Name is too short (minimum is 5 characters)"]
save!
メソッドで保存すると、バリデーションエラーが発生した場合にActiveRecord::RecordInvalidが発生する。
# バリエーションエラーの場合 user.save! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank, Name is too short (minimum is 5 characters)
また、validate: false
を引数で渡すことで、バリデーションの確認をスキップし、DBにレコードを保存することができる。
# Validateが行われない user.save(validate: false) user.save!(validate: false)
モデルを生成し、保存する(createメソッド)
create
メソッドを使えば、new
とsave
メソッドを一度に実行できます。
# モデルの生成と保存 User.create(name: "田中", email: "tanaka@test.co.jp") # バリデーションエラーの発生有無にかかわらず、生成したモデルが返される # バリデーションエラーが発生しなかった時 # => #<User id: 3, name: "aiueoss", password: nil, confirm_password: nil, created_at: "2014-11-23 11:29:47", updated_at: "2014-11-23 11:29:47", active: nil> # バリデーションエラー発生時 # => #<User id: nil, name: nil, password: nil, confirm_password: nil, created_at: nil, updated_at: nil, active: nil> ## create!メソッドを使うと、validationエラー時に例外ActiveRecord::RecordInvalidが発生する
2. モデルの検索
全てのレコードを取得する(allメソッド)
users = User.all # Userテーブルの全てのレコードを取得
最初のレコードと最後のレコードを取得する(first / lastメソッド)
first_user = User.first # 最初のレコードを返す last_user = User.last # 最後のレコードを返す
IDで検索する(findメソッド)
user = User.find(1) # "1"はidのことで、idで検索する users = User.find([1,2,3]) # 配列を引数で渡すことも可能 ## レコードが存在しない場合は以下のActiveRecord::RecordNotFoundが発生する ## ActiveRecord::RecordNotFound: Couldn't find User with 'id'=3
ID以外のカラムで検索する(find_byメソッド)
# emailで検索する user = User.find_by(email: "text@example.com") ## レコードが存在しない場合は、nilを返す
検索条件を指定して検索する(whereメソッド)
SQLのwhereのように検索できる。SQLインジェクションに注意
user = User.where("name = ?", "test") ## 疑問符 ? があることで、適切にエスケープされることを保証してくれるためSQLインジェクションの防止に繋がる # 可読性を上げるために、次のようにも記載できる user = User.where("name = :name", name: "test")
whereメソッドをチェインすることも可能
user = User.where("name = :name", name: "test").where(active: true) # もちろん、メソッドチェインしなくても記載可能 user = User.where("name = :name and active = :active", name: "test", active: true)
部分一致検索(LIKE句の使用)
users = User.where("email like ?", "%" + "gmail.com")
検索順序を指定(orderメソッド)
# pay_typeの昇順(デフォルト)、shipped_atの降順(DESC)で取得する orders = Order.where(name: 'Ruby on Rails Web book').order("pay_type, shipped_at DESC")
取得件数を指定(limitメソッド)
# 最新の5件の注文を取得する orders = Order.order(:created_at).limit(5)
GROUP BY句の使用
summary = LineItem.select("sku, sum(amount as amount").group("sku")
取得する値を指定する(selectメソッド)
Railsはデフォルトでは"select * from ..."で検索をする。しかし、カラムに画像などの大容量のrawデータを含んでいるときなどに、全てのカラムを取得したくないときなどに利用できる。
videos = Video.select("title, speaker, created_at")
関連テーブルの結合(joinsメソッド)
joins
メソッドを使うことで、INNTER JOINが行われる。
Blog.joins(:entries) # => SELECT blogs.* FROM blogs INNER JOIN entries ON entries.blog_id = blogs.id
また、関連テーブルの検索条件を追加することも可能。
entries = Entry.joins(:blog).where("blogs.name LIKE ?", "%me%")
さらに文字列で結合条件を自由に記述することも可能。
User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id") => SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id
列の集計メソッド
average = Order.average(:amount) max = Order.maximum(:amount) min = Order.minimum(:amount) total = Order.sum(:amount) number = Order.count
3. モデルの更新
インスタンスメソッド
カラムに直接代入して更新する
user.name = "やっぱり鈴木" user.save
複数のカラムを更新する(updateメソッド)
user.update( name: "やっぱり鈴木", email: "suzuki@test.co.jp" ) # 更新成功時 => true、更新失敗時 => false
1つのカラムを更新する(update_attributeメソッド)
update_attribute
メソッドは、バリデーションは行われないので注意してください。
user.update_attribute(:name, "やっぱり鈴木")
reloadメソッド
更新したカラムをDBと同じにする。
使用する箇所としては、ユニットテストぐらいしかほぼない。
user.email #=> tanaka@test.co.jp user.update_attribute( {email: "Validatioエラーするemail"} ) # => false user.email # => DBは更新されていないが、値は "Validatioエラーするemail"になってる user.reload.email user.email #=> tanaka@test.co.jp
クラスメソッド
複数のレコードを更新する - update(id, attributes)メソッド
指定したidかその配列に該当するレコードを、指定した属性のセット(ハッシュ)で更新する。
バリデーションは行われないので注意してください。
# idが1のレコードのsaleをtrueにdiscount_rateを0.2に更新する # idが2のレコードのnameをproduct2に更新する product = { 1 => { sale: true, discount_rate: 0.2 }, 2 => { name: 'product2' } } Product.update(product.keys, product.values)
update_all(updates)メソッド
SQLのupdate文のset句とwhere句を指定して、更新する。
バリデーションは行われないので注意してください。
Product.update_all("price = 1.1*price", "title like '%水着'")
4. モデルの削除
インスタンスメソッド
レコードを削除する(destroyメソッド)
# ユーザーレコードをDBから削除する
user.destroy
クラスメソッド
すべてのレコードを削除する(delete_allメソッド)
User.delete_all # => 10 (削除した件数を返す)
以上です。
参考文献
- Active Record Basics — Ruby on Rails Guides
- Rails3 レシピブック 190の技