LoginSignup
6
0

More than 3 years have passed since last update.

Rails6 のちょい足しな新機能を試す76(delete_by destroy_by 編)

Posted at

はじめに

(多分)Rails 6 に追加された新機能を試す第76段。 今回は、 delete_by destroy_by 編です。
Rails 6 では、 ActvieRecord に delete_bydestroy_by が追加されました。
引数に条件を指定して、レコードを削除することができるようになりました。

Ruby 2.6.3, Rails 6.0.0.rc2 で確認しました。

Rails 6.0.0.rc2 は gem install rails -v 6.0.0rc2 --prerelease でインストールできます。
(確認は、Rails 6.0.0 リリース前に実施したものです。)

$ rails --version
Rails 6.0.0.rc2

プロジェクトを作る

$ bin/rails new rails_sandbox
$ cd rails_sandbox

Library と Book モデルを作る

Library は複数の Book オブジェクトを保持します。

$ bin/rails g model library name
$ bin/rails g model book title libray:references

Library モデルを修正する

has_many 関係を追加します。

app/models/library.rb
class Library < ApplicationRecord
  has_many :books, dependent: :destroy
end

seed データを作る

Library, Book ともに複数のデータを作成します。

db/seeds.rb
Library.create(
  [
    {
      name: 'Tokyo',
      books: Book.create(
        [
          { title: 'Programming Ruby' },
          { title: 'The Pragmatic Programmer' },
          { title: 'Agile Web Development with Rails' }
        ]
      )
    },
    {
      name: 'Kanagawa',
      books: Book.create(
        [
          { title: 'Programming Ruby' }
        ]
      )
    },
    {
      name: 'Chiba',
      books: Book.create(
        [
          { title: 'Programming Ruby' },
          { title: 'The Pragmatic Programmer' }
        ]
      )
    }
  ]
)

seed データの投入

DB マイグレーションを実行しデータを登録します。

bin/rails db:create db:migrate db:seed

Rails Console で確認する

rails console で確認します。

Kanagawa Library の Book を delete_by で削除します。

まずは、 Kanagawa で Library を検索します。

irb(main):001:0> library = Library.find_by(name: 'Kanagawa')
  Library Load (0.2ms)  SELECT "libraries".* FROM "libraries" WHERE "libraries"."name" = $1 LIMIT $2  [["name", "Kanagawa"], ["LIMIT", 1]]
=> #<Library id: 2, name: "Kanagawa", created_at: "2019-08-17 00:04:21", updated_at: "2019-08-17 00:04:21">

delete_by で title を条件に指定してデータを削除します。

irb(main):002:0> library.books.delete_by(title: 'Programming Ruby')
  Book Destroy (7.4ms)  DELETE FROM "books" WHERE "books"."library_id" = $1 AND "books"."title" = $2  [["library_id", 2], ["title", "Programming Ruby"]]
=> 1

delete_by で Library も削除します。

irb(main):003:0> Library.delete_by(name: 'Kanagawa')
  Library Destroy (8.1ms)  DELETE FROM "libraries" WHERE "libraries"."name" = $1  [["name", "Kanagawa"]]
=> 1

Tokyo Library の Book を destroy_by で削除します。

まずは、 Tokyo の Library を検索します。

irb(main):004:0> library = Library.find_by(name: 'Tokyo')
  Library Load (0.7ms)  SELECT "libraries".* FROM "libraries" WHERE "libraries"."name" = $1 LIMIT $2  [["name", "Tokyo"], ["LIMIT", 1]]
=> #<Library id: 1, name: "Tokyo", created_at: "2019-08-17 00:04:21", updated_at: "2019-08-17 00:04:21">

destroy_by を使って Book を削除します。

irb(main):005:0> library.books.destroy_by(title: 'The Pragmatic Programmer')
  Book Load (0.2ms)  SELECT "books".* FROM "books" WHERE "books"."library_id" = $1 AND "books"."title" = $2  [["library_id", 1], ["title", "The Pragmatic Programmer"]]
   (0.2ms)  BEGIN
  Book Destroy (0.3ms)  DELETE FROM "books" WHERE "books"."id" = $1  [["id", 2]]
   (3.3ms)  COMMIT
=> [#<Book id: 2, title: "The Pragmatic Programmer", library_id: 1, created_at: "2019-08-17 00:04:21", updated_at: "2019-08-17 00:04:21">]

Library を destroy_by で削除します。

irb(main):006:0> Library.destroy_by(name: 'Chiba')
  Library Load (0.6ms)  SELECT "libraries".* FROM "libraries" WHERE "libraries"."name" = $1  [["name", "Chiba"]]
   (0.3ms)  BEGIN
  Book Load (0.6ms)  SELECT "books".* FROM "books" WHERE "books"."library_id" = $1  [["library_id", 3]]
  Book Destroy (0.6ms)  DELETE FROM "books" WHERE "books"."id" = $1  [["id", 5]]
  Book Destroy (0.5ms)  DELETE FROM "books" WHERE "books"."id" = $1  [["id", 6]]
  Library Destroy (0.8ms)  DELETE FROM "libraries" WHERE "libraries"."id" = $1  [["id", 3]]
   (7.3ms)  COMMIT
=> [#<Library id: 3, name: "Chiba", created_at: "2019-08-17 00:04:21", updated_at: "2019-08-17 00:04:21">]

動作としては

delete_by(*args) は、 where(*arg).delete_all
destroy_by(*arg) は、 where(*arg).destroy_all

同じです。

試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try076_delete_by_destroy_by

参考情報

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0