Railsで既存のデータをもとに新しいデータを作成する

  • 3
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

背景

新しいデータを追加したい。このとき、全部の値を一から記述するのではなく、保存済みのデータをもとに作成したい。
例えば、

方法

dupを使う。例えば、下記のような書籍のデータがあるとき、これを元に続刊のデータを追加したいとする。

[2] pry(main)> Book.first
  Book Load (0.2ms)  SELECT  "books".* FROM "books"  ORDER BY "books"."id" ASC LIMIT 1
=> #<Book:0x007fe80c35d9e0
 id: 1,
 title: "book_1",
 description: "desc",
 price: 1000,
 created_at: Fri, 01 Apr 2016 05:32:20 UTC +00:00,
 updated_at: Fri, 01 Apr 2016 05:32:20 UTC +00:00>

dupを使うと以下の様なデータが出来上がる。id,created_at,updated_atnilになっている点に注目。

[3] pry(main)> Book.first.dup
  Book Load (0.2ms)  SELECT  "books".* FROM "books"  ORDER BY "books"."id" ASC LIMIT 1
=> #<Book:0x007fe80c26e700
 id: nil,
 title: "book_1",
 description: "desc",
 price: 1000,
 created_at: nil,
 updated_at: nil>

後は複製されたデータを変更し、saveすれば追加できる。

[5] pry(main)> book.title = 'book_2'
=> "book_2"
[6] pry(main)> book.save
   (0.1ms)  begin transaction
  SQL (0.3ms)  INSERT INTO "books" ("title", "description", "price", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["title", "book_2"], ["description", "desc"], ["price", 1000], ["created_at", "2016-04-01 05:33:52.992514"], ["updated_at", "2016-04-01 05:33:52.992514"]]
   (2.1ms)  commit transaction
=> true

保存された内容を見ると、新しく作成されていることがわかる。

[13] pry(main)> Book.all
  Book Load (0.1ms)  SELECT "books".* FROM "books"
=> [#<Book:0x007fe80c7a9cd8
  id: 1,
  title: "book_1",
  description: "desc",
  price: 1000,
  created_at: Fri, 01 Apr 2016 05:32:20 UTC +00:00,
  updated_at: Fri, 01 Apr 2016 05:32:20 UTC +00:00>,
 #<Book:0x007fe80c7a98f0
  id: 2,
  title: "book_2",
  description: "desc",
  price: 1000,
  created_at: Fri, 01 Apr 2016 05:33:52 UTC +00:00,
  updated_at: Fri, 01 Apr 2016 05:33:52 UTC +00:00>]

注意:clonedupは挙動が異なる

"複製"をキーワードにメソッドを探そうとするとcloneが見つかるが、これはdupと挙動が異なるので注意。

[10] pry(main)> book = Book.first
[11] pry(main)> book == book.dup
=> false
[12] pry(main)> book == book.clone
=> true