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

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

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

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

Ruby on Rails

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

Q&A

解決済

1回答

1446閲覧

Rails 2つのフォームから1つのDBにデータ登録ができない

ruby_0ct

総合スコア57

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2017/12/26 19:15

ブログ記事の投稿フォームでDBに格納したいと思っています。
DBは「ブログ本体のDB」と「カテゴリー用のDB」の2つがあります。

投稿フォームで、ブログタイトルや本文のフォームとカテゴリーを選択するフォーム、2つのフォームがあり、
カテゴリーフォームは「カテゴリー用のDB」から参照し、 collection_select でプルダウン表示させています。

buildメソッドや accepts_nested_attributes_for などを記述し、2つのフォームの関係性を認識させようとしましたが、

NoMethodError in BlogsController#new undefined method `blogcategories' for nil:NilClass @blog.blogcategories.build

とエラー表示され、うまくできません。

様々なサイトを見て同じように buildメソッド を書いたのですがなぜこうなるのかよくわからずいまいちピンとこないので、ご指摘いただければ助かります。

また、DBの関係は1つの記事につき、1つのカテゴリーしか参照できませんが、カテゴリーからはいくつもの記事に参照できる「1対多」の関係です。

###blogs_controller.rb
createアクションは手をつけていません。

ruby

1def new 2 @blog.blogcategories.build 3 4 @dbsort = Blogcategory.new # カテゴリーの表示 5end 6 7 8def create 9 @blog = Blog.new(blog_params) 10 11 respond_to do |format| 12 if @blog.save 13 format.html { render :index } 14 format.json { render :show, status: :created, location: @blog } 15 else 16 format.html { render :new } 17 format.json { render json: @blog.errors, status: :unprocessable_entity } 18 end 19 end 20end 21 22 23private 24 def blog_params 25 params.require(:blog).permit(:blogtitle, :blogcategory_id, :content, blogs_attributes[:blogcategory_id]) 26 end

###/views/blogs/new.html.erb
投稿フォームのview
カテゴリーの部分はプルダウン(select)で表示させています。

ruby

1<h1>ブログを投稿する</h1> 2 3 <%= form_for(@blog) do |f| %> 4 <% if @blogchou.errors.any? %> 5 <div id="error_explanation"> 6 <h2><%= pluralize(@blog.errors.count, "error") %> prohibited this blog from being saved:</h2> 7 8 <ul> 9 <% @blog.errors.full_messages.each do |message| %> 10 <li><%= message %></li> 11 <% end %> 12 </ul> 13 </div> 14 <% end %> 15 16 <%= f.text_field :blogtitle, placeholder: 'ブログタイトル' %> 17 18 <%= form_for @dbsort do |c| %> 19 <%= c.collection_select :id, Blogcategory.all, :id, :category %> 20 <% end %> 21 22 <%= f.text_field :content, placeholder: 'ブログの内容' %> 23 24 <%= f.submit 'ブログを投稿する' %></div> 25 <% end %> 26

###/models/blogcategory.rb
カテゴリー用DBのモデル

ruby

1class Blogcategory < ApplicationRecord 2 has_many :blogs 3 accepts_nested_attributes_for :blogs, allow_destroy: true 4end

###/models/blog.rb
ブログ本体DBのモデル

ruby

1class Blog < ApplicationRecord 2 belongs_to :blogcategory 3end

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

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

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

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

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

guest

回答1

0

ベストアンサー

エラーメッセージの

undefined method `blogcategories' for nil:NilClass

は,NilClass クラスのインスタンスである nilblogcategories というメソッドは定義されていない,ということです。

とすれば,@blognil であると分かります。

BlogsControllernew メソッドを見ると,いきなり

rb

1 @blog.blogcategories.build

で始まっていますね。

before_action などで @blog をセットしているのでなければ,ここで初めて @blog が出てくるのですが,「未定義のインスタンス変数の値は nil」というルールがあるので,nilblogcategories メソッドを呼び出そうとしていることになるのです。

(追記)

エラーの原因は以上ですが,new メソッドで最初にやるべきことはおそらく

rb

1@blog = Blog.new

で空の(フォーム用の)Blog オブジェクトを作ることでしょうね。

で,Blog モデルの定義を見ると

rb

1belongs_to :blogcategory

なので,そもそも Blogblogcategories というメソッドはありません。(複数あるはずがありませんよね)
belong_to の解説(参考にしたもの)をもう一度よく読んでみてください。
今の場合,blogcategory という単数形のメソッドが使えます。

ただ,new メソッドで @blog.blogcategory.build ってやる必要がよくわかりません。

また,フォームが入れ子になっているのもよく分かりません。
Blog のためのフォームなので,カテゴリーを選ぶところは category_id の値を select させればよいと思うのですが。

投稿2017/12/26 23:14

編集2017/12/26 23:26
scivola

総合スコア2108

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

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

ruby_0ct

2017/12/27 17:47

@blog.build_blogcategory とすることで無事表示されました。 実はsubmitしても無反応だったためbuildあたりが怪しいからではないかと推測し、この質問をしたのですが、buildしても相変わらず無反応なため、buildではなくform_forの入れ子の部分とルーティングの仕方が原因ではないかとわかりました。 また改めて調べて実際にやってみたいと思います。 丁寧にご指摘いただきbuildについて大変参考になりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問