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

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

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

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

Q&A

解決済

2回答

601閲覧

requireを設定するとエラーが出る

tamtamtime

総合スコア8

Ruby on Rails 6

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

0グッド

0クリップ

投稿2023/01/15 07:02

編集2023/01/15 07:21

前提

コントローラーでrequireを設定するとエラーが出ます。

実現したいこと

投稿した画像にタグ付けをしたいです。

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

ActionController::ParameterMissing in DesignsController#create param is missing or the value is empty: post_form

該当のソースコード

ruby

1[app>controllers>designs_controller.rb] 2 3class DesignsController < ApplicationController 4 before_action :authenticate_user!, only:[:edit, :new, :destroy] 5 before_action :move_to_index, except: [:index, :show] 6 before_action :set_design, only: [:show, :edit] 7 8 def index 9 @designs = Design.includes(:user).order("created_at DESC") 10 end 11 12 def new 13 @designs = Design.new 14 end 15 16 def create 17 @designs = Design.create(design_params) 18 if 19 @designs.save 20 redirect_to root_path 21 else 22 render :new 23 end 24 end 25 26 def show 27 28 end 29 30 def destroy 31 design = Design.find(params[:id]) 32 if design.destroy 33 redirect_to root_path 34 end 35 end 36 37 def update 38 design = Design.find(params[:id]) 39 if 40 design.update(design_params) 41 redirect_to design_path(design.id) 42 else 43 redirect_to request.referer 44 end 45 end 46 47 def edit 48 unless user_signed_in? && current_user.id == @design.user_id 49 redirect_to action: :index 50 end 51 end 52 53 def search 54 @designs = Design.search(params[:keyword]).order("created_at DESC") 55 end 56 57 private 58 59 def design_params 60 params.require(:post_form).permit(:title, :file_name, :image).merge(user_id: current_user.id) 61 end 62 63 def set_design 64 @design = Design.find(params[:id]) 65 end 66 67 def move_to_index 68 unless user_signed_in? 69 redirect_to action: :index 70 end 71 end 72 73end

ruby

1[app>models>post_form.rb] 2 3class PostForm 4 include ActiveModel::Model 5 6 attr_accessor( 7 :title, :file_name, :image, 8 :id, :created_at, :updated_at, 9 :tag_name 10 ) 11 12 with_options presence: true do 13 validates :title 14 validates :file_name 15 validates :image 16 end 17 18 def save 19 designs = Design.create(text: text, image: image) 20 tag = Tag.where(tag_name: tag_name).first_or_initialize 21 tag.save 22 PostTagRelation.create(design_id: design.id, tag_id: tag.id) 23 end 24

ruby

1[app>models>post_tag_relation.rb] 2class PostTagRelation < ApplicationRecord 3 belongs_to :design 4 belongs_to :tag 5end

ruby

1[app>models>design.rb] 2 3class Design < ApplicationRecord 4 belongs_to :user 5 has_many :post_tag_relations 6 has_many :tags, through: :post_tag_relations 7 has_one_attached :image 8 9 validates :title, presence: true 10 validates :file_name, presence: true 11 validates :image, presence: true 12 13 def self.search(search) 14 if search != "" 15 Design.where('title LIKE(?)', "%#{search}%") 16 else 17 Design.all 18 end 19 end 20 21 22 23end

ruby

1[app>views>show.html.erb] 2 3<main class="main"> 4 <div class="inner"> 5 <div class="prototype__wrapper"> 6 <p class="prototype__hedding"> 7 <%= @design.title %> 8 </p> 9 <% if user_signed_in? && current_user.id == @design.user_id %> 10 <div class="prototype__detail"><br> 11 <p class="detail__title">ファイル場所</p> 12 <p class="detail__message"> 13 <%= @design.file_name %> 14 </p> 15 </div> 16 <% end %> 17 18 <span class="tag_style"><%= @design.tags.first&.tag_name %></span> 19 20 <div class="prototype__image"> 21 <%= image_tag @design.image %> 22 </div> 23 </div> 24 </div> 25</main>

ruby

1[app>views>designs>_form.html.erb] 2<%= form_with model: @design, url: url, method: method, id: 'new_post', local: true do |f| %> 3 4 <div class="field"> 5 <%= f.label :title, "タイトル" %><br /> 6 <%= f.text_field :title, id:"design_title" %> 7 </div> 8 9 <div class="field"> 10 <%= f.label :file_name, "ファイル名" %><br /> 11 <%= f.text_area :file_name, class: :form__text, id:"design_file_name" %> 12 </div> 13 14 <div class="field"> 15 <%= f.label :image, "画像" %><br /> 16 <%= f.file_field :image, id:"design_image" %> 17 </div> 18 19 <div class="tag-field"> 20 <%= f.text_field :tag_name, placeholder: 'add tags' %> 21 </div> 22 23 <div class="actions"> 24 <%= f.submit "保存する", class: :form__btn %> 25 </div> 26<% end %>

試したこと

requireを削除すると正常に表示されるのですが
今度はタグの保存・表示ができなくなります。

補足情報(FW/ツールのバージョンなど)

初心者でして、初歩的な質問かと思いますが、何卒宜しくお願いいたします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

PostForm の save メソッドを拝見したところ、 create しか対応してないようですので、update の考慮は不要ってことで良いですかね?
とりあえず create だけ考えて回答します。

--

普通に Rails のモデルを使ってフォームを作る場合は、モデル名から「パラメータ名」や「送信先」を推測してくれるんですが、今回は独自のフォームクラスを作られているようなので、オプションを使って設定を上書きする必要があります。
あと、 model オプションの指定も変なので、これも修正が必要です。

1・【model】 PostForm クラスを指定するのではなく、 PostForm クラスのインスタンスを指定します。
2・【送信先】 DesignsController#create に送信したいので、 url: designs_path, method: :post と書きます。
3・【パラメータ名】 require の名前に合わせて scope: :post_form と書きます。

diff

1[app>views>designs>_form.html.erb] 2 3- <%= form_with model:PostForm, url: new_design_path, local: true do |f| %> 4+ <%= form_with model: @post_form, url: design_path, method: :post, scope: :post_form, local: true do |f| %> 5 6※※※ 事前に @post_form を作る必要があるので、コントローラー側にも修正が必要です。後述します ※※※

コントローラー側で PostForm を使うように変更します。

diff

1[app>controllers>designs_controller.rb] 2 3 def new 4- @designs = Design.new 5+ @post_form = PostForm.new 6 end 7 8 def create 9- @designs = Design.create(design_params) 10+ @post_form = PostForm.new(design_params) 11 12- if @designs.save 13+ if @post_form.save 14 redirect_to root_path 15 else 16 render :new 17 end 18 end

あと、パラメータの名前が view と controller で異なっているので、これも修正してください。
(誤 tag → 正 tag_name

diff

1 def design_params 2- params.require(:post_form).permit(:title, :file_name, :tag, :image).merge(user_id: current_user.id) 3+ params.require(:post_form).permit(:title, :file_name, :tag_name, :image).merge(user_id: current_user.id) 4 end

PostForm の処理もちょっと変なので直しましょう。

diff

1class PostForm 2 include ActiveModel::Model 3 4 attr_accessor( 5 :title, :file_name, :image, 6- :id, :created_at, :updated_at, 7+ :id, :user_id, 8+ # ↑ created_at と updated_at は画面から受け取るパラメータではないので不要だと思います。 9+ # ↑ 逆に user_id は design_params に含まれているので必要だと思います。 10 :tag_name 11 ) 12 13 with_options presence: true do 14 validates :title 15 validates :file_name 16 validates :image 17 end 18 19 def save 20+ # ↓ 複数モデルを扱うのでトランザクションが必須です。 21+ ActiveRecord::Base.transaction do 22 23- designs = Design.create(text: text, image: image) 24+ design = Design.create!(title: title, text: text, image: image, user_id: user_id) 25+ # ↑ title に必須バリデーションを設定しているのに、保存時に使ってないのはおかしいと思います。 26+ # ↑ user_id も必要ではないですか? 27+ # ↑ トランザクションのために「 ! 」を付けます。 28+ # ↑ 単一のレコードなのに変数名が複数形なのはおかしいです。 29 30 tag = Tag.where(tag_name: tag_name).first_or_initialize 31- tag.save 32+ tag.save! 33+ # ↑ トランザクションのために「 ! 」を付けます。 34 35- PostTagRelation.create(design_id: design.id, tag_id: tag.id) 36+ PostTagRelation.create!(design_id: design.id, tag_id: tag.id) 37+ # ↑ トランザクションのために「 ! 」を付けます。 38 39+ end 40 41+ return true 42+ # ↑ 「 save! 」や「 create! 」が一つもエラーにならなかったら true を返す。 43 44+ rescue 45+ false 46+ # ↑ 「 save! 」や「 create! 」が一つでもエラーになったら false を返す。 47 48 end

--

多分これで最低限 create が動くと思います。お試しください。

「一つの design に複数の tag を付ける」とか「update にも対応させる」とかやりたい場合は別途修正が必要です。

投稿2023/01/16 09:41

shinoharat

総合スコア1676

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

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

0

ruby

1[app>controllers>designs_controller.rb] 2def design_params 3 params.require(:post_form).permit(:title, :file_name, :tag, :image).merge(user_id: current_user.id) 4 end

ruby

1[app>views>designs>_form.html.erb] 2<%= form_with model:PostForm, url: new_design_path, local: true do |f| %>

上記でエラーは出なくなりましたがタグが保存されず、表示もされません…。

投稿2023/01/15 08:08

編集2023/01/15 08:13
tamtamtime

総合スコア8

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

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

shinoharat

2023/01/16 08:33

送信先が new アクションになったから、「design_params」が呼び出されなくなってエラーが消えただけですね。 保存したいなら create アクションに飛ばす必要があります。
tamtamtime

2023/01/18 01:15 編集

ご回答、コメントありがとうございます!! 勉強になる事も多々あり、本当にありがとうございます!! PostFormを修正したのですが、以下のようなエラーが出ました。 NameError in DesignsController#create undefined local variable or method `text' for #<PostForm:0x00007fd374f5d3a0> Did you mean? test Extracted source (around line #20): 18 def save 19 design = Design.create!(title: title, text: text, image: image, user_id: user_id) 20 tag = Tag.where(tag_name: tag_name).first_or_initialize 21 tag.save! 22 PostTagRelation.create!(design_id: design.id, tag_id: tag.id) 「text」を「file_name」に変更してもエラーになるのですが、どこかおかしいのでしょうか? 度々恐れ入ります、ご教示のほど何卒お願いいたします。
shinoharat

2023/01/18 01:53

すみません、見落としていました。 対応としては > 「text」を「file_name」に変更 で合ってると思います。 保存処理を design = Design.create!(title: title, file_name: file_name, image: image, user_id: user_id) に変えて実行し、表示されるエラーメッセージを教えてください。
tamtamtime

2023/01/18 03:06 編集

ありがとうございます!タグ保存されました! 本当にありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問