seed_fuを使って初期データを作成
以前seed_fuを使ってデータを作成したことがあったのですが、そのときには出会わなかったエラーに遭遇したので、記録として残しておきます。
以前書いたブログ seed_fuを使って初期データを作成 - 学習記録
ユーザーテーブルと日記テーブルの初期データを作成していきます。
まず最初にGemfile
にseed_fu
のgem
を追加してbundle install
します。
gem 'seed-fu'
seedファイルを置くためのディレクトリを作成します。
$ mkdir db/fixtures $ mkdir db/fixtures/development $ mkdir db/fixtures/production $ mkdir db/fixtures/test
開発環境のUserテーブルとDiaryテーブルにデータを作成していきたいと思います。まずdevelopment配下に下記2つのファイルを用意します。
$ touch db/fixtures/development/users.rb $ touch db/fixtures/development/diaries.rb
日記のデータを作成していきます。このようなデータをidを変えて20個作成しました。
Diary.seed do |s| s.id = 1 s.feeling = '😆' s.body = '⛱🐠' s.start_time = Date.yesterday s.user_id = 1 end
ユーザーのデータを作成します。id、nickname、nameを変えて10個作成しました。
User.seed do |s| s.id = 1 s.nickname = 'sayo' s.name = 'kimsayo' s.password = "password" end
そして開発環境のデータを作成しようとコマンドを叩くと、エラーに。。InvalidForeignKey
となっているのですが、外部キーの設定が無効?
$ rails db:seed_fu RAILS_ENV=development == Seed from /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/db/fixtures/development/diaries.rb - Diary {:id=>1, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>1} - Diary {:id=>2, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>2} - Diary {:id=>3, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>3} rails aborted! ActiveRecord::InvalidForeignKey: Mysql2::Error: Cannot add or update a child row: a foreign key constraint fails (`emoji_diary_development`.`diaries`, CONSTRAINT `fk_rails_f03fd03c63` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/rails:5:in `<top (required)>' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:10:in `block in <top (required)>' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:7:in `tap' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:7:in `<top (required)>' Caused by: Mysql2::Error: Cannot add or update a child row: a foreign key constraint fails (`emoji_diary_development`.`diaries`, CONSTRAINT `fk_rails_f03fd03c63` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/rails:5:in `<top (required)>' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:10:in `block in <top (required)>' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:7:in `tap' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:7:in `<top (required)>' Tasks: TOP => db:seed_fu (See full trace by running task with --trace)
日記のデータを作るときに失敗しているのかな?と思ったので、user_idの指定の仕方を少し変えて再度試してみました。
Diary.seed do |s| s.id = 20 s.feeling = '😆' s.body = '⛱🐠' s.start_time = Date.today s.user_id = User.find(10) end
またエラーです。NotNullViolation
、user_id
がnullになってしまっているらしい。。よくみてみるとuserのデータが全て入ってしまっています。これがエラーになる原因ですね。
$ rails db:seed_fu RAILS_ENV=development == Seed from /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/db/fixtures/development/diaries.rb - Diary {:id=>1, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>#<User id: 1, nickname: "sayo", name: "kimura34", crypted_password: "$2a$10$uIOXd191ACl0YkrVBwDvweTWj7T8XFkm4IpvMkkzGvb...", salt: "xkBkgsz_i9KxjRjyG2-X", created_at: "2021-05-22 17:06:12.899598000 +0900", updated_at: "2021-05-22 17:06:12.899598000 +0900">} rails aborted! ActiveRecord::NotNullViolation: Mysql2::Error: Field 'user_id' doesn't have a default value /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/rails:5:in `<top (required)>' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:10:in `block in <top (required)>' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:7:in `tap' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:7:in `<top (required)>' Caused by: Mysql2::Error: Field 'user_id' doesn't have a default value /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/rails:5:in `<top (required)>' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:10:in `block in <top (required)>' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:7:in `tap' /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/bin/spring:7:in `<top (required)>' Tasks: TOP => db:seed_fu (See full trace by running task with --trace)
調べてみると、Userのデータが入る前に、DiaryがUserを参照しようとしてしまっているからみたいです。なのでシードデータの順番を制御することで解決するようです。seedのファイル名を下記のようにしました。
db/fixtures/development/01_users.rb db/fixtures/development/02_diaries.rb
データを作成することができました。
$ rails db:seed_fu RAILS_ENV=development == Seed from /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/db/fixtures/development/01_users.rb - User {:id=>1, :nickname=>"sayo", :name=>"kimsayo", :password=>"password"} - User {:id=>2, :nickname=>"eri", :name=>"eri1112", :password=>"password"} - User {:id=>3, :nickname=>"yuka", :name=>"yuka911", :password=>"password"} - User {:id=>4, :nickname=>"ayaka", :name=>"110aya", :password=>"password"} - User {:id=>5, :nickname=>"asa", :name=>"asako", :password=>"password"} - User {:id=>6, :nickname=>"yuki", :name=>"bu8yuki", :password=>"password"} - User {:id=>7, :nickname=>"rina", :name=>"rina93", :password=>"password"} - User {:id=>8, :nickname=>"yuna", :name=>"yunana", :password=>"password"} - User {:id=>9, :nickname=>"nami", :name=>"namihe", :password=>"password"} - User {:id=>10, :nickname=>"mari", :name=>"maririn", :password=>"password"} == Seed from /Users/SAYO/workspace/portfolio/emoji_diary/emoji_diary/db/fixtures/development/02_diaries.rb - Diary {:id=>1, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>1} - Diary {:id=>2, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>2} - Diary {:id=>3, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>3} - Diary {:id=>4, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>4} - Diary {:id=>5, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>5} - Diary {:id=>6, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>6} - Diary {:id=>7, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>7} - Diary {:id=>8, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>8} - Diary {:id=>9, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>9} - Diary {:id=>10, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Tue, 01 Jun 2021, :user_id=>10} - Diary {:id=>11, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Wed, 02 Jun 2021, :user_id=>1} - Diary {:id=>12, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Wed, 02 Jun 2021, :user_id=>2} - Diary {:id=>13, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Wed, 02 Jun 2021, :user_id=>3} - Diary {:id=>14, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Wed, 02 Jun 2021, :user_id=>4} - Diary {:id=>15, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Wed, 02 Jun 2021, :user_id=>5} - Diary {:id=>16, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Wed, 02 Jun 2021, :user_id=>6} - Diary {:id=>17, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Wed, 02 Jun 2021, :user_id=>7} - Diary {:id=>18, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Wed, 02 Jun 2021, :user_id=>8} - Diary {:id=>19, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Wed, 02 Jun 2021, :user_id=>9} - Diary {:id=>20, :feeling=>"😆", :body=>"⛱🐠", :start_time=>Wed, 02 Jun 2021, :user_id=>10}
作成されたユーザーの情報に問題がありました。user_id
が1と2のユーザーのpassword
のデータはちゃんと入っているのですが、user_id
が3以降のユーザーのパスワードがnil
になっていました。
irb(main):001:0> User.all User Load (51.0ms) SELECT `users`.* FROM `users` /* loading for inspect */ LIMIT 11 => #<ActiveRecord::Relation [#<User id: 1, nickname: "sayo", name: "kimsayo", crypted_password: "$2a$10$uIOXd191ACl0YkrVBwDvweTWj7T8XFkm4IpvMkkzGvb...", salt: "xkBkgsz_i9KxjRjyG2-X", created_at: "2021-05-22 17:06:12.899598000 +0900", updated_at: "2021-06-02 17:56:01.179817000 +0900">, #<User id: 2, nickname: "eri", name: "eri1112", crypted_password: "$2a$10$ebAXC5bqM0y8ZA9F/PIuF.2C6n5dSCbG6WUaMduqGQc...", salt: "SbmP96di6H6L9u8n7hyD", created_at: "2021-05-22 17:15:10.416046000 +0900", updated_at: "2021-05-22 17:15:10.416046000 +0900">, #<User id: 3, nickname: "yuka", name: "yuka911", crypted_password: nil, salt: nil, created_at: "2021-06-02 17:56:01.234058000 +0900", updated_at: "2021-06-02 17:56:01.234058000 +0900">, #<User id: 4, nickname: "ayaka", name: "110aya", crypted_password: nil, salt: nil, created_at: "2021-06-02 17:56:01.241600000 +0900", updated_at: "2021-06-02 17:56:01.241600000 +0900">, #<User id: 5, nickname: "asa", name: "asako", crypted_password: nil, salt: nil, created_at: "2021-06-02 17:56:01.245346000 +0900", updated_at: "2021-06-02 17:56:01.245346000 +0900">, #<User id: 6, nickname: "yuki", name: "bu8yuki", crypted_password: nil, salt: nil, created_at: "2021-06-02 17:56:01.249030000 +0900", updated_at: "2021-06-02 17:56:01.249030000 +0900">, #<User id: 7, nickname: "rina", name: "rina93", crypted_password: nil, salt: nil, created_at: "2021-06-02 17:56:01.255090000 +0900", updated_at: "2021-06-02 17:56:01.255090000 +0900">, #<User id: 8, nickname: "yuna", name: "yunana", crypted_password: nil, salt: nil, created_at: "2021-06-02 17:56:01.261832000 +0900", updated_at: "2021-06-02 17:56:01.261832000 +0900">, #<User id: 9, nickname: "nami", name: "namihe", crypted_password: nil, salt: nil, created_at: "2021-06-02 17:56:01.264915000 +0900", updated_at: "2021-06-02 17:56:01.264915000 +0900">, #<User id: 10, nickname: "mari", name: "maririn", crypted_password: nil, salt: nil, created_at: "2021-06-02 17:56:01.270509000 +0900", updated_at: "2021-06-02 17:56:01.270509000 +0900">]>
seedファイルの書き方を今一度確認してみます。
User.seed do |s| s.id = 1 s.nickname = 'sayo' s.name = 'kimsayo' s.password = "password" end User.seed do |s| s.id = 2 s.nickname = 'eri' s.name = 'eri1112' s.password = "password" end User.seed do |s| s.id = 3 s.nickname = 'yuka' s.name = 'yuka911' s.password = "password" end User.seed do |s| s.id = 4 s.nickname = 'ayaka' s.name = '110aya' s.password = "password" end User.seed do |s| s.id = 5 s.nickname = 'asa' s.name = 'asako' s.password = "password" end
password
とプラスでpassword_cofirmaiton
を追加してみようと思います。
User.seed do |s| s.id = 1 s.nickname = 'sayo' s.name = 'kimsayo' s.password = "password" s.password_confirmation = "password" end User.seed do |s| s.id = 2 s.nickname = 'eri' s.name = 'eri1112' s.password = "password" s.password_confirmation = "password" end User.seed do |s| s.id = 3 s.nickname = 'yuka' s.name = 'yuka911' s.password = "password" s.password_confirmation = "password" end User.seed do |s| s.id = 4 s.nickname = 'ayaka' s.name = '110aya' s.password = "password" s.password_confirmation = "password" end User.seed do |s| s.id = 5 s.nickname = 'asa' s.name = 'asako' s.password = "password" s.password_confirmation = "password" end
rails console
で調べてみます。
irb(main):001:0> User.all User Load (6.9ms) SELECT `users`.* FROM `users` /* loading for inspect */ LIMIT 11 => #<ActiveRecord::Relation [#<User id: 1, nickname: "sayo", name: "kimsayo", crypted_password: "password", salt: "password", created_at: "2021-05-22 17:06:12.899598000 +0900", updated_at: "2021-06-05 11:00:21.640283000 +0900">, #<User id: 2, nickname: "eri", name: "eri1112", crypted_password: "password", salt: "password", created_at: "2021-05-22 17:15:10.416046000 +0900", updated_at: "2021-06-05 11:00:21.654480000 +0900">, #<User id: 3, nickname: "yuka", name: "yuka911", crypted_password: "password", salt: "password", created_at: "2021-06-02 17:56:01.234058000 +0900", updated_at: "2021-06-05 11:00:21.659504000 +0900">, #<User id: 4, nickname: "ayaka", name: "110aya", crypted_password: "password", salt: "password", created_at: "2021-06-02 17:56:01.241600000 +0900", updated_at: "2021-06-05 11:00:21.662597000 +0900">, #<User id: 5, nickname: "asa", name: "asako", crypted_password: "password", salt: "password", created_at: "2021-06-02 17:56:01.245346000 +0900", updated_at: "2021-06-05 11:00:21.665946000 +0900">, #<User id: 6, nickname: "yuki", name: "bu8yuki", crypted_password: "password", salt: "password", created_at: "2021-06-02 17:56:01.249030000 +0900", updated_at: "2021-06-05 11:00:21.670000000 +0900">, #<User id: 7, nickname: "rina", name: "rina93", crypted_password: "password", salt: "password", created_at: "2021-06-02 17:56:01.255090000 +0900", updated_at: "2021-06-05 11:00:21.673932000 +0900">, #<User id: 8, nickname: "yuna", name: "yunana", crypted_password: "password", salt: "password", created_at: "2021-06-02 17:56:01.261832000 +0900", updated_at: "2021-06-05 11:00:21.678020000 +0900">, #<User id: 9, nickname: "nami", name: "namihe", crypted_password: "password", salt: "password", created_at: "2021-06-02 17:56:01.264915000 +0900", updated_at: "2021-06-05 11:00:21.687091000 +0900">, #<User id: 10, nickname: "mari", name: "maririn", crypted_password: "password", salt: "password", created_at: "2021-06-02 17:56:01.270509000 +0900", updated_at: "2021-06-05 11:00:21.692096000 +0900">, ...]>
password
は入っているように見えるのですが、全然ログインができません。。暗号化されていないからかな?と思ったので、パスワードの書き方を少し変えてみました。
参考 : https://qiita.com/reflet/items/eeced34f9c5c2a9fbaf6#暗号化そのものを行う関数
User.seed( :id, { id: 1, nickname: 'sayo', name: 'kimsayo', crypted_password: User.encrypt('password') }, { id: 2, nickname: 'eri', name: 'eri1112', crypted_password: User.encrypt('password') }, { id: 3, nickname: 'yuka', name: 'yuka911', crypted_password: User.encrypt('password') }, { id: 4, nickname: 'miki', name: 'mickey', crypted_password: User.encrypt('password') }, { id: 5, nickname: 'yuki', name: 'yuki8', crypted_password: User.encrypt('password') }, { id: 6, nickname: 'ayaka', name: 'ayaka110', crypted_password: User.encrypt('password') }, { id: 7, nickname: 'asa', name: 'asako', crypted_password: User.encrypt('password') }, { id: 8, nickname: 'mari', name: 'mari7', crypted_password: User.encrypt('password') }, { id: 9, nickname: 'yuna', name: 'yuna61', crypted_password: User.encrypt('password') }, { id: 10, nickname: 'hina', name: 'hina4', crypted_password: User.encrypt('password') }, )
rails consoleで確かめてみるとsaltは未だ入っていなかったのですが、ログインできる情報は入っているのでOKです。
irb(main):001:0> User.all User Load (2.4ms) SELECT `users`.* FROM `users` /* loading for inspect */ LIMIT 11 => #<ActiveRecord::Relation [#<User id: 1, nickname: "sayo", name: "kimsayo", crypted_password: "$2a$10$xIWJ0vGGQ3TKMrFo52XNj.4an2CEobjzH6nA4crF/Sf...", salt: nil, created_at: "2021-06-05 12:16:43.581614000 +0900", updated_at: "2021-06-05 12:16:43.581614000 +0900">, #<User id: 2, nickname: "eri", name: "eri1112", crypted_password: "$2a$10$1Ojfr/S1IddywFPlkk9oNueWv81/LUA7z8Kf0ZWscu9...", salt: nil, created_at: "2021-06-05 12:16:43.587105000 +0900", updated_at: "2021-06-05 12:16:43.587105000 +0900">, #<User id: 3, nickname: "yuka", name: "yuka911", crypted_password: "$2a$10$uJtj9DG4283XqTOUObhMVOy3ee2t0dR.Cab/mUoRQLv...", salt: nil, created_at: "2021-06-05 12:16:43.592558000 +0900", updated_at: "2021-06-05 12:16:43.592558000 +0900">, #<User id: 4, nickname: "miki", name: "mickey", crypted_password: "$2a$10$p.aV4X8F6Xmn/RG/0wL5hO1cw.6rgs2qEbcU7v6EQSk...", salt: nil, created_at: "2021-06-05 12:16:43.595620000 +0900", updated_at: "2021-06-05 12:16:43.595620000 +0900">, #<User id: 5, nickname: "yuki", name: "yuki8", crypted_password: "$2a$10$MijtD1ZqwjdCGTyLuTuB7efHQFTBndffBhKUHsnKDPu...", salt: nil, created_at: "2021-06-05 12:16:43.598516000 +0900", updated_at: "2021-06-05 12:16:43.598516000 +0900">, #<User id: 6, nickname: "ayaka", name: "ayaka110", crypted_password: "$2a$10$1Pe2Uj.7DURX4HS11tL9.uUK3UZ7IGxWn.pSO47A5OZ...", salt: nil, created_at: "2021-06-05 12:16:43.601421000 +0900", updated_at: "2021-06-05 12:16:43.601421000 +0900">, #<User id: 7, nickname: "asa", name: "asako", crypted_password: "$2a$10$M/nYjlWnvo6ur7uhLVV4g.9uFJgqtII0GLK5l.UzS2a...", salt: nil, created_at: "2021-06-05 12:16:43.604262000 +0900", updated_at: "2021-06-05 12:16:43.604262000 +0900">, #<User id: 8, nickname: "mari", name: "mari7", crypted_password: "$2a$10$qIkdzXxvvAXtbsxPoRQgUO346iEwLX.Ga3s5pRB/Lyz...", salt: nil, created_at: "2021-06-05 12:16:43.606981000 +0900", updated_at: "2021-06-05 12:16:43.606981000 +0900">, #<User id: 9, nickname: "yuna", name: "yuna61", crypted_password: "$2a$10$5KTdmiWhHQaoFGh4nCkF1OW5ctaj5meqV1osK9UONPk...", salt: nil, created_at: "2021-06-05 12:16:43.610756000 +0900", updated_at: "2021-06-05 12:16:43.610756000 +0900">, #<User id: 10, nickname: "hina", name: "hina4", crypted_password: "$2a$10$.QoTsvb0tJSH7dQ5ZNBSOeqnEqCUclTt0qd3OviLNXq...", salt: nil, created_at: "2021-06-05 12:16:43.614056000 +0900", updated_at: "2021-06-05 12:16:43.614056000 +0900">, ...]>