🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

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

Ruby on Rails

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

ルーティング

ルーティングとは、TCP/IPネットワークにおいて、目的のホストまでパケットを送る為のパス選定のプロセスを言います。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1249閲覧

NoMethodError in ContentsController#createが解決できない

kaaaawaaaa

総合スコア1

Ruby

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

Ruby on Rails

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

ルーティング

ルーティングとは、TCP/IPネットワークにおいて、目的のホストまでパケットを送る為のパス選定のプロセスを言います。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2021/03/21 13:43

編集2021/03/21 14:15

前提・実現したいこと

rails で情報共有掲示板を作成中です。
ある金融機関のあるカテゴリーに対して、その内容を登録したいのですが、
エラーが発生し、解決できていない状況です。
※テーブルはユーザー・金融機関・カテゴリー・コンテンツの4つです。
イメージとしては、「A銀行」の「残高」は「5000円」と登録したいのですが、できていません。

発生している問題・エラーメッセージ

イメージ説明

該当のソースコード

ContentsController

1class ContentsController < ApplicationController 2 3 def index 4 @banks = Bank.all #サイドバーに必要(共通) 5 @content =Content.new 6 @bank = Bank.find(params[:bank_id]) 7 @contents = @bank.contents 8 @categories = @bank.categories.select(:subject) 9 end 10 11 def new 12 @content = Content.new 13 @banks = Bank.all #サイドバーに必要(共通) 14 @bank = Bank.find(params[:bank_id]) 15 @categories = @bank.categories.select(:subject) 16 @category = Category.find(params[:category_id]) 17 end 18 19 def create 20 @bank = Bank.find(params[:bank_id]),Category.find(params[:category_id]) 21 @test = Bank.find(params[:bank_id]) 22 @categories = @test.categories.select(:subject) 23 @content = @bank.contents.new(content_params) 24 if @content.save 25 redirect_to bank_contents_path(@bank),notice: "登録しました。" 26 else 27 @contents = @bank.contents.includes(:category) 28 redirect_to bank_contents_path(@bank),notice: "登録に失敗しました。" 29 end 30 end 31 32 private 33 def content_params 34 params.require(:content).permit(:detail,:bank_id,:category_id,:user_id).merge(user_id: current_user.id) 35 end 36end

登録フォームのあるHTML

new

1<div class="wrapper"> 2 3 <div class="side-bar"> 4 <%= render "categories/side_bar" %> 5 </div> 6 7 <div class="page-header"> 8 <div class="header-title"> 9 <%= @bank.name %> 10 </div> 11 <% if flash[:notice] %> 12 <p><%= flash[:notice] %></p> 13 <% end %> 14 </div> 15</div> 16 17 <div class="content"> 18 <div class="category_detail"> 19 <div class="group"> 20 <%= @category.subject %> 21 <%= form_with model: [@bank,@category,@content], class: 'form', local: true do |f| %> 22 <div class="form-input"> 23 <%= f.text_field :detail, class: 'form-message', placeholder: '最新情報を登録' %> 24 <%= f.submit '登録', class: 'form-submit' %> 25 </div> 26 <% end %> 27 </div> 28 </div> 29 </div>

登録フォームへ遷移するHTML

index

1<div class="wrapper"> 2 3 <div class="side-bar"> 4 <%= render "categories/side_bar" %> 5 </div> 6 7 <div class="page-header"> 8 <div class="header-title"> 9 <%= @bank.name %> 10 </div> 11 <% if flash[:notice] %> 12 <p><%= flash[:notice] %></p> 13 <% end %> 14 </div> 15</div> 16 17 <div class="content"> 18 <div class="category_detail"> 19 <% @bank.categories.each do |category| %> 20 <div class="group"> 21 <%=link_to category.subject,new_bank_category_content_path(@bank.id ,category.id) %> 22 <%= @content.detail %> 23 </div> 24 <% end %> 25 </div> 26 </div>

ルーティング

routes

1Rails.application.routes.draw do 2 devise_for :users 3 root to: "categories#index" 4 resources :users, only: [:edit, :update] 5 resources :categories, only: [:new, :create] 6 resources :banks, only: [:new, :create, :destroy, :edit, :update] do 7 resources :contents, only: [:index, :create, :new] 8 end 9 10 resources :banks, only: [:new, :create, :destroy, :edit, :update] do 11 resources :categories, only: [:new, :create] do 12 resources :contents, only: [:index, :create, :new] 13 end 14 end 15end 16 17 18```テーブル設計 19banks(金融機関)テーブル 20|id|name| 21|:--:|:--:| 22|1|A銀行| 23 24categories(カテゴリー)テーブル 25|id|subject| 26|:--:|:--:| 27|1|残高| 28|2|商品名| 29 30bank_categories(中間)テーブル 31|id|bank_id|category_id| 32|:--:|:--:|:--:| 33|1|1|1| 34|2|1|2| 35 36contents(内容)テーブル 37|id|detail|bank_id|category_id|user_id| 38|:--:|:--:|:--:|:--:|:--:| 39|1|5000円|1|1|1| 40|2|Aローン|1|2|1| 41 42モデル 43```bank 44class Bank < ApplicationRecord 45 has_many :bank_categories 46 has_many :categories, through: :bank_categories 47 has_many :contents 48 49 validates :name, presence: true 50 validates :name, uniqueness: true 51end

category

1class Category < ApplicationRecord 2 has_many :bank_categories 3 has_many :banks, through: :bank_categories 4 has_many :contents 5 6 validates :subject, uniqueness: true 7 validates :number, uniqueness: true 8end

bankcategory

1class BankCategory < ApplicationRecord 2 belongs_to :bank 3 belongs_to :category 4end

content

1class Content < ApplicationRecord 2 belongs_to :bank 3 belongs_to :category 4 belongs_to :user 5 6 validates :detail, presence: true 7 validates :bank_id, presence: true 8 validates :category_id, presence: true 9 validates :user_id, presence: true 10end

※上記テーブルのように情報が登録できればベストだと考えています。

試したこと

@contentが正しく設定できていないのではないかと思いましたがうまくいきませんでした。
※IDをとる必要があると考え、ルーティングを今回のように設定しております。

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

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

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

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

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

guest

回答1

0

ベストアンサー

Bankモデルに

ruby

1has_many :contents

で関連付けはできていますでしょうか?この関連付けがないと@bank.contentsは呼び出せないですね

あと

ruby

1@bank = Bank.find(params[:bank_id]),Category.find(params[:category_id])

ruby

1,Category.find(params[:category_id])

の部分は誤字ですかね?もし意図的に加えたものであるならば、外しておきましょう

>>>>>>>>>追記

has_many :contentsはあるのですね

new.html.erb
<%= form_with model: [@bank,@category,@content], class: 'form', local: true do |f| %>

<%= form_with model: @content, class: 'form', local: true do |f| %>

contents_controller.rb
※testは不要なコードだとお見受けしたので省略
def create
@bank = Bank.find(params[:bank_id])
@content = @bank.contents.new(content_params)

一旦、ここまで修正してエラーがどう変化するか見てみたいです。
おそらく、ここまで変更すると、残りはcontent_paramsをどうするか、という課題だけが残るかと思います。

当初、
@bank = Bank.find(params[:bank_id]),Category.find(params[:category_id])
と書いていたので、@bankにはBankのオブジェクトだけでなくCategoryオブジェクトも入ってしまっていたため、@bankにはオブジェクトの配列ができてしまっていました。
その証拠にundefined methods contents for <Array xxxxxx....>とエラー文が示すように、Array(=配列)にはcontentsはないですよ、というエラーになってしまっています。

ので、一旦コードをスッキリさせるために、Bankだけを取得するように書いてみる、ということです。

form_withの修正については、modelに複数書くことに意味がないため削除した、という理由だけです。

上記、一旦確認してみてください。お願いいたします。

>>>>>>>>>>追記の追記 2021.3.22 08:30

次のエラーが
'''ruby
undefined method `contents_path' for #<#Class:0x00007fb61254a4f0:0x00007fb61d13f8c8>
'''
ですね。
次は

html

1<%= form_with model: @content, url: bank_category_contents_path, class: 'form', local: true do |f| %>

に直せばたぶんいけるんじゃないかなと思います。もしくは、

html

1<%= form_with model: @content, url: [@bank, @category, :contents], method: :post, class: 'form', local: true do |f| %>

かなぁ。

こちらはform_withで生成されたformのURLがルーティングで見つからないよ、というエラーです。
今回のようにmodelに@contentと設定すると、contents_pathが自動で設定されるようになります。

しかし、routes.rbの設定を伺うと、contents_pathに該当するパスはなく、かつ、ご希望を叶えるとするならばbanks/id/categories/id/contentsのパスを生成しなければなりません。
そのため、別途urlオプションにURLパスを指定してあげる必要があります。

後者のほうはパスの別の書き方になります。上の方法がうまくいかなければお試しください。

これで、次にどういったエラーが出るかまた確認したいです。よろしくお願いいたします。

>>>>>>>>>>>>>>追記の追記の追記 2021.3.22 21:30
前回の修正により次の課題がcontent_paramsのエラー解消となったみたいですので、

ruby

1params.require(:content).permit(:detail,:bank_id,:category_id,:user_id).merge(category_id: category.id ,user_id: current_user.id)

ruby

1params.require(:content).permit(:detail).merge(bank_id: params[:bank_id], category_id: params[:category_id] ,user_id: current_user.id)

に変更して見てください。これで登録できるようになるはず…

エラーコードにParameterとして

ruby

1{"authenticity_token"=>"Tdl19kGEpFdkQQsgEFHAKhHV4ef1idrapjM73+whvV89uRcWbR2njvyCGwwn3cbU8sqFiwfgQWd8arMK8sdQMw==", 2"content"=>{"detail"=>"5000"}, 3"commit"=>"登録", 4"bank_id"=>"2", 5"category_id"=>"1"}

が記載されていたと思います。こちらがparamsの値の正体です。Railsを使い始めたばかりでparamsにどんな値が入っているのかわからない、という場合にはエラーを出した際にこちらの値を確認するとわかりやすいです。他の機能を実装する際の参考にしてみてください。

投稿2021/03/21 13:58

編集2021/03/22 12:05
yoshi_10_11

総合スコア241

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

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

kaaaawaaaa

2021/03/21 14:26

ご回答ありがとうございます。 Bankモデルへのhas_many :contentsの記載はできていましたので、問題はございませんでした。 「,Category.find(params[:category_id])」についてはcategory_idを取得する上で必要であろうと思い記載しておりました。 ※外して試したところ登録に失敗してしまいました。(contents_controller内のストロングパロメーターの部分にmergeでカテゴリIDを追加するように記載してみました(category_id: category.idと追記))
yoshi_10_11

2021/03/21 15:52

has_many :contentsはあるのですね new.html.erb <%= form_with model: [@bank,@category,@content], class: 'form', local: true do |f| %> ↓ <%= form_with model: @content, class: 'form', local: true do |f| %> contents_controller.rb ※testは不要なコードだとお見受けしたので省略 def create @bank = Bank.find(params[:bank_id]) @content = @bank.contents.new(content_params) 一旦、ここまで修正してエラーがどう変化するか見てみたいです。 おそらく、ここまで変更すると、残りはcontent_paramsをどうするか、という課題だけが残るかと思います。 当初、 @bank = Bank.find(params[:bank_id]),Category.find(params[:category_id]) と書いていたので、@bankにはBankのオブジェクトだけでなくCategoryオブジェクトも入ってしまっていたため、@bankにはオブジェクトの配列ができてしまっていました。 その証拠にundefined methods contents for <Array xxxxxx....>とエラー文が示すように、Array(=配列)にはcontentsはないですよ、というエラーになってしまっています。 ので、一旦コードをスッキリさせるために、Bankだけを取得するように書いてみる、ということです。 form_withの修正については、modelに複数書くことに意味がないため削除した、という理由だけです。 上記、一旦確認してみてください。お願いいたします。
kaaaawaaaa

2021/03/21 22:20

大変ご丁寧にありがとうございます。下記内容に修正してみました。 new.html.erb <%= form_with model: @content, class: 'form', local: true do |f| %> contents_controller.rb  def create @bank = Bank.find(params[:bank_id]) @content = @bank.contents.new(content_params) と修正しました。内容登録画面に入るところでエラーとなりました。 NoMethodError in Contents#new Showing /Users/kawanishimasaya/ai-app/ai-hosho-ebb/app/views/contents/new.html.erb where line #21 raised: undefined method `contents_path' for #<#<Class:0x00007fb61254a4f0>:0x00007fb61d13f8c8> Did you mean? content_tag Extracted source (around line #21): 19 <div class="group"> 20  <%= @category.subject %> 21  <%= form_with model: @content, class: 'form', local: true do |f| %> 22   <div class="form-input"> 23    <%= f.text_field :detail, class: 'form-message', placeholder: '最新情報を登録' %> 24    <%= f.submit '登録', class: 'form-submit' %> Rails.root: /Users/kawanishimasaya/ai-app/ai-hosho-ebb Application Trace | Framework Trace | Full Trace app/views/contents/new.html.erb:21 Request Parameters: {"bank_id"=>"2", "category_id"=>"1"}
yoshi_10_11

2021/03/21 23:20

ありがとうございます。 ちょっとコメントだとコードが読みにくくなるので、回答の部分を編集して次のコードをお伝えしますのでお待ち下さい!
kaaaawaaaa

2021/03/22 11:05

二通り試してみました。双方ともに同じエラー文でした。 内容を見るとおそらくストロングパロメーターに問題があるのではないかと思っています。 NameError in ContentsController#create undefined local variable or method `category' for #<ContentsController:0x00007ff205fd9e00> Did you mean? categories_url Extracted source (around line #34): 32  private 33 def content_params 34  params.require(:content).permit(:detail,:bank_id,:category_id,:user_id).merge(category_id: category.id ,user_id: current_user.id) 35  end 36 end Rails.root: /Users/kawanishimasaya/ai-app/ai-hosho-ebb Application Trace | Framework Trace | Full Trace app/controllers/contents_controller.rb:34:in `content_params' app/controllers/contents_controller.rb:23:in `create' Request Parameters: {"authenticity_token"=>"Tdl19kGEpFdkQQsgEFHAKhHV4ef1idrapjM73+whvV89uRcWbR2njvyCGwwn3cbU8sqFiwfgQWd8arMK8sdQMw==", "content"=>{"detail"=>"5000"}, "commit"=>"登録", "bank_id"=>"2", "category_id"=>"1"}
kaaaawaaaa

2021/03/22 14:32

夜分遅くに申し訳ございません。 yoshi_10_11さんのおかげで解決することができました! また、パラメーターの意味やエラーの意味もよく理解することができ、 私自身の学習にもなりました。感謝でいっぱいです!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問