前提・実現したいこと
リレーション先のテーブルを参照して、クライアント画面にcontentを一覧表示する処理を実現したいです。
ER図
モデル
rb
1#user.rb 2class User < ApplicationRecord 3 has_many :contents 4end
rb
1#content.rb 2class Content < ApplicationRecord 3 belongs_to :user 4end
テストデータ
rb
1#seed.rb 2require "securerandom" 3 4User.create!(username: 'test', email: 'admin@test.com', password: 'password', confirmed_at: Time.now) 5 699.times do |n| 7 username = SecureRandom.urlsafe_base64(10) 8 email = "example-#{n+1}@plathoth.com" 9 password = "password" 10 User.create!(username: username, 11 email: email, 12 password: password, 13 confirmed_at: Time.now) 14end 15 16users = User.order(:created_at).take(6) 1750.times do |n| 18 title = "testのイメージ#{n+1}" 19 summary = Faker::Lorem.sentence(5) 20 view = rand(10000) 21 media = open("#{Rails.root}/db/fixtures/00.jpg") 22 users.each { |user| user.contents.create!(title: title, 23 summary: summary, 24 view: view, 25 media: media) } 26end
現在Content側にバリデーションは設定しておりません。
既にseedデータは作成している状況です。
発生している問題・エラーメッセージ
rails c
で新規のuserを作ってからcontentを参照すると、無事にcontentを参照できます。
[1] pry(main)> user = User.create(username: 'admin', email: 'admin@admin.com', password: 'password', confirmed_at: Time.now) user.contents (0.5ms) SAVEPOINT active_record_1 User Exists (0.5ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'admin@admin.com' LIMIT 1 User Create (0.8ms) INSERT INTO `users` (`email`, `encrypted_password`, `confirmed_at`, `created_at`, `updated_at`, `username`) VALUES ('admin@admin.com', '$2a$12$319lUAPEZprnQH3Wm0NSpuN7quUfXkJ1HW.mMDCXQWS5lapUGpX9W', '2020-09-28 05:19:46', '2020-09-28 05:19:46', '2020-09-28 05:19:46', 'admin') (0.4ms) RELEASE SAVEPOINT active_record_1 => #<User id: 104, email: "admin@admin.com", created_at: "2020-09-28 05:19:46", updated_at: "2020-09-28 05:19:46", provider: nil, uid: nil, username: "admin"> [2] pry(main)> user.contents => Content Load (0.6ms) SELECT `contents`.* FROM `contents` WHERE `contents`.`user_id` = 101 [] [3] pry(main)> user.contents.create(title: "aaaaaa", summary:"bbbbbbb", view:11111112) (0.6ms) SAVEPOINT active_record_1 Content Create (0.6ms) INSERT INTO `contents` (`title`, `summary`, `view`, `user_id`, `created_at`, `updated_at`) VALUES ('aaaaaa', 'bbbbbbb', 11111112, 101, '2020-09-28 03:49:54', '2020-09-28 03:49:54') (0.3ms) RELEASE SAVEPOINT active_record_1 => #<Content:0x000055ddca79fcb8 id: 301, title: "aaaaaa", summary: "bbbbbbb", view: 11111112, media: nil, user_id: 101, created_at: Mon, 28 Sep 2020 12:49:54 JST +09:00, updated_at: Mon, 28 Sep 2020 12:49:54 JST +09:00> [4] pry(main)> user.contents.where(user_id: 101) => Content Load (1.2ms) SELECT `contents`.* FROM `contents` WHERE `contents`.`user_id` = 101 AND `contents`.`user_id` = 101 [#<Content:0x000055ddcab77930 id: 301, title: "aaaaaa", summary: "bbbbbbb", view: 11111112, media: nil, user_id: 101, created_at: Mon, 28 Sep 2020 12:49:54 JST +09:00, updated_at: Mon, 28 Sep 2020 12:49:54 JST +09:00>]
このことから、リレーションは機能していると考えられます。
しかし、テストデータを用いて同じことをしようとすると
[1] pry(main)> user = User.where(id: 1) => User Load (0.6ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 [#<User id: 1, email: "admin@test.com", created_at: "2020-09-27 11:30:09", updated_at: "2020-09-27 11:30:09", provider: nil, uid: nil, username: "hadson">] [2] pry(main)> user.contents NoMethodError: undefined method `contents' for #<User::ActiveRecord_Relation:0x000055f5bd252f98> from /usr/local/bundle/gems/activerecord-5.2.4.4/lib/active_record/relation/delegation.rb:125:in `method_missing'
となり、contentsが存在しないと返されます。
ほとんど同じ処理をしているにも関わらず、なぜ後者ではcontentsがNoMethodErrorになるのでしょうか?テストデータが関連づけられていないとしたら、seedを作成する時点でエラーになりテストデータは作成されなくなるはずでです。テストデータが作成されるということは、contentsを参照できるはずなので尚更おかしいと感じました。
分かる方いらっしゃればご教授頂けると嬉しいです。
補足情報(FW/ツールのバージョンなど)
Mac Catalina 10.15.6
Rails 5.2.3
ruby 2.6.3p62
mysql:5.7
nginx:1.16
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/28 05:45 編集
2020/09/28 06:06
2020/09/28 06:07
2020/09/28 08:51
2020/09/28 08:53
2020/09/28 09:03
2020/09/28 09:06
2020/09/28 09:12
2020/09/28 09:17