質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

1回答

811閲覧

[Rails]リレーション先のテーブルを参照できない

zyno

総合スコア41

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

1クリップ

投稿2020/09/28 05:27

編集2020/09/28 05:31

前提・実現したいこと

リレーション先のテーブルを参照して、クライアント画面に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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

なぜ後者ではcontentsがNoMethodErrorになるのでしょうか?

エラーメッセージの通り、userUserではありません。.whereした結果は、リレーションとなっています。

1つだけのモデルを取得したい場合は、user = User.find(1)、あるいはuser = User.find_by(id: 1)のようにしましょう。

投稿2020/09/28 05:37

maisumakun

総合スコア145203

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zyno

2020/09/28 05:45 編集

userに`User.where`した結果が入ってくるため、user.contentsで参照できるものだと考えているのですが、実はそうではないということですか?前者で同じことをしたら上手くいっていたのでどうしてNoMethodErrorになってしまうのでしょうか? また、試しに` User.contents`を実行したところ [1] pry(main)> User.contents NoMethodError: undefined method `contents' for #<Class:0x000055c830cba428> Did you mean? constants from /usr/local/bundle/gems/activerecord-5.2.4.4/lib/active_record/dynamic_matchers.rb:22:in `method_missing' と返されました。 恐らく私の中で何らかの基礎的な知識が抜け落ちて今回応募した疑問になっていると考えています。
maisumakun

2020/09/28 06:06

> userに`User.where`した結果が入ってくるため、user.contentsで参照できるものだと考えているのですが、実はそうではないということですか? はい、whereの結果はモデルそのものではありません。
maisumakun

2020/09/28 06:07

「user = User.find(1)」あるいは「user = User.find_by(id: 1)」については試されましたでしょうか?
zyno

2020/09/28 08:51

「user = User.find(1)」あるいは「user = User.find_by(id: 1)」で試したら動きました。User.where,User.find,User.contentsはあくまで動くかどうかを試すために仮置きしたもので、本来はcontentの値をリレーション先から一覧表示するために @contents = User.contents.all もしくは users = User.all users.each do |user| @contents = user.contents.paginate(page: params[:page]) end のような形でインスタンス変数に値を入れ込み、それをviewで表示するのがゴールです。前者だとNoMethodErrorになり、後者だと動きはしますがデバッグで値を追っていくと途中までは値が入っているのに、最終的な値が空白になってしまいviewに表示されません。 なぜこのようになってしまうのか理解できていません。よろしければヒントのようなものを頂いてもよろしいでしょうか?
maisumakun

2020/09/28 08:53

@contents = Content.allではだめですか?
zyno

2020/09/28 09:03

@contents = Content.allをするとsyntaxerrorになってしまうので尚更訳がわからないといった状態です
maisumakun

2020/09/28 09:06

周辺部まで書いていただけませんか? (@contents = Content.all単体ではSyntaxErrorにはならないかと思います)
zyno

2020/09/28 09:12

class PagesController < ApplicationController def index # @users = User.all # users = User.all # users.each do |user| # @contents = user.contents.paginate(page: params[:page]) # end @content = Content.all end def show end end // views/pages/index.html.erb <ol class="contents col-md-3"> <%= render @contents %> </ol> になります!
zyno

2020/09/28 09:17

@contents = Content.allの件、自己解決しました! ・MacでVSCodeを使って日本語入力すると不可視文字(バグ)が出現する場合がある ・全角文字を1文字変換中、確定せずDeleteキーで削除すると発生することがある ・0x08とは制御文字、バックスペースのこと らしく、全て消して一から書き直したら動きました。お手数おかけしてしまい申し訳ありません。ありがとうございます https://tattaka-s.hatenablog.com/entry/2019/07/06/153703
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問