4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

gem ancestry + seedファイルを利用した、データベースへの複数カラム挿入

Last updated at Posted at 2020-04-02

本記事について

Ruby on Railsのseedファイルを使って、ancestryのデータを挿入するとき、カラムを複数同時に挿入したいと思い、その実装ができたので解説させていただきます。
(とあるプログラミングスクールのカリキュラムによって、某フリマアプリのカテゴリーに関する記事がたくさんありますが、そちらはカラムが1つしかなかったため投稿しようと考えました。)

目的

  1. seedファイルを使ってデータベースを作成すること
  2. データベース作成時に複数のカラムを同時に生成すること

参考資料

Qiita参考記事
【Rails】ancestryで簡単に多階層型データの作成し呼び出す
railsのseedの書き方いろいろ
Rails・seedファイルを分割して管理する

事前準備

ancestryの基本的な導入方法はたくさん記事があるので、割愛させていただきます。
gemのインストール、モデルの定義、テーブルの作成まで終わったものとします。

実践

今回はfood(食材)のテーブルを作成し、seedファイルで複数のカラムを同時に挿入してみます。
完成後のテーブルはこのような感じです。
データベースのサンプル.png

ancestryのgemを使っているので、「ancestry」のカラムはこのように自動的に入ります。
今回実践するカラムの同時挿入は、「name」と「description(説明)」です。
ではいきましょう。

seedファイルにデータの書き込み

テーブルに登録するデータを書き込み、データを作成するようにcreateメソッドで定義してあげます。
今回はこのようになります。

db/seeds.rb
parent_array = [
  {name: "野菜", description: "健康を保つための栄養が取れる食材"},
  {name: "果物", description: "食を彩る栄養価も高い食材"}
]

vegetable_child_array = [
  {name: "根菜類", description: "根っこの部分を食べる野菜"},
  {name: "葉菜類", description: "葉っぱの部分を食べる野菜"}
]

vegetable_grandchild_array = [
  [ # 野菜 >> 根菜類
  {name: "大根", description: "火を通すと甘味が増す野菜"},
  {name: "にんじん", description: "鮮やかな橙色の野菜"}
  ],[ # 野菜 >> 葉菜類
  {name: "ほうれん草", description: "鉄分が豊富な野菜"},
  {name: "レタス", description: "シャキシャキとした食感が特徴の野菜"}
  ]
]

parent = Food.create(parent_array[0])
vegetable_child_array.each_with_index do |child,i|
  child = parent.children.create(name: child[:name], description: child[:description])
  vegetable_grandchild_array[i].each do |grandchild|
    child.children.create(name: grandchild[:name], description: grandchild[:description])
  end
end


fruit_child_array = [
  {name: "仁果類", description: "花の先端部分が膨らんで果実になる果物"},
  {name: "柑橘類", description: "ビタミンCやクエン酸を多く含む果物"}
]

fruit_grandchild_array = [
  [ # 果物 >> 仁果類
  {name: "りんご", description: "甘い蜜を含んだ果実"},
  {name: "なし", description: "水分を多く含んだ甘い果物"}
  ],[ # 果物 >> 柑橘類
  {name: "みかん", description: "橙色の甘い果物"},
  {name: "レモン", description: "酸味が特徴的な果物"}
  ]
]

parent = Food.create(parent_array[1])
fruit_child_array.each_with_index do |child,i|
  child = parent.children.create(name: child[:name], description: child[:description])
  fruit_grandchild_array[i].each do |grandchild|
    child.children.create(name: grandchild[:name], description: grandchild[:description])
  end
end

少し長いですが、このようになります。
記述の方法はいろいろあるので、一例と思って見てください。

ここで大事なのが、createする時に、

~ xx.create(name: child[:name], description: child[:description])

と記述することで、カラムを指定して登録できます。実は結構簡単でした。

データの挿入

続いて、データを挿入していきます。
ターミナルで、以下のコマンドを実行します。

$ rails db:seed

これで、エラーメッセージが出なければ、データが挿入されているのができるはずです。
データの読み込みが成功したときは、何もメッセージが出ないはずです。

[追記]
データの読み込みが成功したときは何もメッセージが出ませんが、
メッセージが出なくても読み込みに失敗している時がありました。
そんな時は、createメソッドをcreate!メソッドにすることでエラーの内容が見れるようになります。

# create!メソッド使用時
$ rails db:seed

=> rake aborted!
ActiveRecord::RecordInvalid: バリデーションに失敗しました: Userを入力してください

上記の例は、modelにアソシエーションの記述をした状態だったため、読み込みがされていないのに何もメッセージが出ていませんでした。特定するのには、create!メソッドが便利なので使うことをおすすめします。

注意点

seedファイルを読み込むときは、テーブルに作成済みのレコードがないか確認してから行いましょう。
重複するデータがあるとエラーで弾かれてしまいます。

最後に

seedファイルの読み込みは、慣れるまで結構大変に感じました。
エラーの原因がわかりにくいので、根気よくがんばってください!

4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?