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

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

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

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

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

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

RubyMine

RubyMineは、Ruby/Ruby on RailsベースのWebアプリケーション開発を行うためのIDEです。コードエディタやコードアシスタンス、グラフィカルなデバッガを搭載しており、様々なバージョン管理システムに対応しています。

Q&A

解決済

2回答

1522閲覧

投稿内容を編集するとエラーが起きる

yuu0000

総合スコア4

Ruby

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

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

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

RubyMine

RubyMineは、Ruby/Ruby on RailsベースのWebアプリケーション開発を行うためのIDEです。コードエディタやコードアシスタンス、グラフィカルなデバッガを搭載しており、様々なバージョン管理システムに対応しています。

0グッド

0クリップ

投稿2021/05/15 09:28

投稿内容を編集しようとするとパラメーターが無いとエラーが生じる

現在、投稿内容を編集する機能を作成しているのですが、投稿内容を編集しようとすると下記のようなエラーが起きる。

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

ActionController::ParameterMissing in UploadsController#update param is missing or the value is empty: upload_form Did you mean? upload id controller _method Extracted source (around line #58): 56 57 58 59 60 def upload_params params.require(:upload_form).permit(:title, :text, :url, :working_day, :day_off, :cafe_wifi_id, :cafe_charging_id, :cafe_smoking_id, :image, :name).merge(user_id: current_user.id)⇦この部分 end end Extracted source (around line #34): 32 33 34 35 36 37 def update @upload = Upload.find(params[:id]) @upload_form = UploadForm.new(upload_params, upload: @upload)⇦この部分 tag_list = params[:upload][:name].split(",") if @upload_form.valid? @upload_form.save(tag_list)

formオブジェクトを用いて編集機能を作成しているため、モデルの処理などはupload_form.rbというファイルに作成しております。

該当するエラー部分に関するコードなどを確認してみましたが、どの部分を修正する必要があるのか原因が掴めない状況です。

エラーに関する原因やヒントなどをご教授願えますでしょうか。

該当のソースコード

app/views/uploads/edit.html.erb

erb

1<%= render "shared/header" %> 2 3<div class="upload-form-contents"> 4 <div class="upload-form"> 5 <h2 class="upload-form__title">カフェの情報を編集</h2> 6 <%= form_with(model: @upload_form, url: upload_path, local: true) do |f| %> 7 8 <%# カフェ画像 %> 9 <div class="img-upload"> 10 <div class="upload-text"> 11 カフェの画像 12 <span class="important">必須</span> 13 </div> 14 <div class="click-upload"> 15 <p> 16 クリックしてファイルをアップロード 17 </p> 18 <%= f.file_field :image, id: "item-image" %> 19 </div> 20 </div> 21 <%# カフェ名とカフェの説明%> 22 <div class="cafe-item"> 23 <div class="upload-text"> 24 カフェ名 25 <span class="important">必須</span> 26 </div> 27 <%= f.text_area :title, class: "cafe-text", id: "uploads-name", placeholder: "カフェ名 (必須 40字まで)", maxlength: "40" %> 28 <div class="cafe-explain"> 29 <div class="upload-text"> 30 カフェの説明 31 <span class="important">必須</span> 32 </div> 33 <%= f.text_area :text, class: "cafe-text", id: "cafe-info", placeholder: "カフェの説明 (必須 1000字まで) こちらのカフェでは充電はもちろんのことwifiまで完備されているので,外で作業をする人におすすめです。", rows: "7", maxlength: "1000" %> 34 </div> 35 <div class="upload-tag"> 36 <div class="upload-text"> 37 タグ 38 <span class="important">必須</span> 39 </div> 40 <%= f.text_field :name, class: "uploads-field", id: "cafe-tag", placeholder: "タグを入力。複数の場合は,で区切る", maxlength: "20" %> 41 </div> 42 <div class="upload-text"> 43 URL 44 </div> 45 <%= f.text_field :url, class: "uploads-field", id: "cafe-url", placeholder: "カフェのURL", maxlength: "60" %> 46 <div class="upload-text"> 47 営業時間 48 </div> 49 <%= f.text_field :working_day, class: "uploads-field", id: "cafe-working_day", placeholder: "平日10:00~20:00 土日祝9:00~20:00", maxlength: "60" %> 50 <div class="upload-text"> 51 定休日 52 </div> 53 <%= f.text_field :day_off, class: "uploads-field", id: "cafe-day-off", placeholder: "火曜日", maxlength: "60" %> 54 </div> 55 <%# カフェの詳細%> 56 <div class="upload-detail"> 57 <div class="upload-text">カフェの詳細</div> 58 <div class="upload-form-detail"> 59 <div class="upload-text"> 60 店内のwifi 61 <span class="important">必須</span> 62 </div> 63 <%= f.collection_select(:cafe_wifi_id, CafeWifi.all, :id, :name, {}, { class: "select-box", id: "uploads-cafe-wifi" }) %> 64 <div class="upload-text"> 65 充電コンセント 66 <span class="important">必須</span> 67 </div> 68 <%= f.collection_select(:cafe_charging_id, CafeCharging.all, :id, :name, {}, { class: "select-box", id: "uploads-cafe-charging" }) %> 69 <div class="upload-text"> 70 喫煙について 71 <span class="important">必須</span> 72 </div> 73 <%= f.collection_select(:cafe_smoking_id, CafeSmoking.all, :id, :name, {}, { class: "select-box", id: "uploads-cafe-smoking" }) %> 74 </div> 75 </div> 76 <%# 投稿ボタン %> 77 <div class="upload-btn-contents"> 78 <%= f.submit "更新する", class: "uploads-form-btn" %> 79 <%= link_to 'トップページへ', root_path, class: "back-btn" %> 80 </div> 81 <% end %> 82 </div> 83</div>

app/models/upload_form.rb

model

1class UploadForm 2 include ActiveModel::Model 3 attr_accessor :title, :text, :url, :working_day, :day_off, :cafe_wifi_id, :cafe_charging_id, :cafe_smoking_id, 4 :user_id, :image, :name 5 6 with_options presence: true do 7 validates :title 8 validates :text 9 validates :cafe_wifi_id 10 validates :cafe_charging_id 11 validates :cafe_smoking_id 12 validates :user_id 13 validates :image 14 validates :name 15 validates :upload_id, presence: true 16 validates :tag_id, presence: true 17 end 18 19 with_options numericality: { other_than: 0 } do 20 validates :cafe_wifi_id 21 validates :cafe_charging_id 22 validates :cafe_smoking_id 23 end 24 25 delegate :persisted?, to: :upload 26 27 def initialize(attributes = nil, upload: Upload.new) 28 @upload = upload 29 attributes ||= default_attributes 30 super(attributes) 31 end 32 33 def save(tag_list) 34 35 ActiveRecord::Base.transaction do 36 @upload.update(title: title, text: text, url: url, working_day: working_day, day_off: day_off, cafe_wifi_id: cafe_wifi_id, cafe_charging_id: cafe_charging_id, cafe_smoking_id: cafe_smoking_id, user_id: user_id, image: image) 37 38 @upload.upload_tags_relation.each do |tag| 39 tag.delete 40 end 41 42 tag_list.each do |tag_name| 43 tag = Tag.where(name: tag_name).first_or_initialize 44 tag.save 45 46 upload_tag_relation = UploadTagRelation.where(upload_id: upload.id, tag_id: tag.id).first_or_initialize 47 upload_tag_relation.update(upload_id: upload.id, tag_id: tag.id) 48 49 end 50 end 51 # upload = Upload.create(title: title, text: text, url: url, working_day: working_day, day_off: day_off, cafe_wifi_id: cafe_wifi_id, cafe_charging_id: cafe_charging_id, cafe_smoking_id: cafe_smoking_id, user_id: user_id, image: image) 52 # map = Map.create(address: address, latitude: latitude, longitude: longitude, upload_id: upload_id) 53 end 54 55 def to_model 56 upload 57 end 58 59 private 60 61 attr_reader :upload 62 63 def default_attributes 64 { 65 title: upload.title, 66 text: upload.text, 67 url: upload.url, 68 working_day: upload.working_day, 69 day_off: upload.day_off, 70 cafe_wifi_id: upload.cafe_wifi_id, 71 cafe_charging_id: upload.cafe_charging_id, 72 cafe_smoking_id: upload.cafe_smoking_id, 73 image: upload.image, 74 name: upload.tags.pluck(:name).join(",") 75 } 76 end 77end

app/controllers/uploads_controller

controller

1class UploadsController < ApplicationController 2 def index 3 @uploads = Upload.all.order(created_at: :desc) 4 @tag_list = Tag.all 5 end 6 7 def new 8 @upload_form = UploadForm.new 9 end 10 11 def create 12 @upload_form = UploadForm.new(upload_params) 13 tag_list = params[:upload_form][:name].split(",") 14 if @upload_form.valid? 15 @upload_form.save(tag_list) 16 redirect_to root_path 17 else 18 render new 19 end 20 end 21 22 def show 23 @upload = Upload.find(params[:id]) 24 @tag = @upload.tags 25 end 26 27 def edit 28 @upload = Upload.find(params[:id]) 29 @upload_form = UploadForm.new(upload: @upload) 30 end 31 32 def update 33 @upload = Upload.find(params[:id]) 34 @upload_form = UploadForm.new(upload_params, upload: @upload) 35 tag_list = params[:upload][:name].split(",") 36 if @upload_form.valid? 37 @upload_form.save(tag_list) 38 redirect_to upload_path(@upload.id) 39 else 40 render :edit 41 end 42 end 43 44 def destroy 45 @upload = Upload.find(params[:id]) 46 @upload.image.purge if @upload.image.attached? 47 if @upload.destroy 48 redirect_to root_path 49 else 50 render :show 51 end 52 53 end 54 55 private 56 57 def upload_params 58 params.require(:upload_form).permit(:title, :text, :url, :working_day, :day_off, :cafe_wifi_id, :cafe_charging_id, :cafe_smoking_id, :image, :name).merge(user_id: current_user.id) 59 end 60end 61

試したこと

・paramsが取得できていないことが原因なので、edit,updateアクションのコードに不足がないか確認してみたが、この部分にエラーが発生するコードがあるとは考えずらかった。
・formオブジェクト内の記述に原因がないか確認してみたところ、saveアクションの中に必要な処理は記述されていた。
・edit.html.erbのform_with modelの記述に問題がないか確認してみたが原因が掴めなかった。

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

開発環境
・rubymine
・ruby(3.0.1)
・Ruby on rails (6.1.3.1)
Githubのリポジトリ
https://github.com/yuuffff1212/locat

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

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

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

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

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

guest

回答2

0

自己解決

カスタムメソッドの定義方法が難しかったため、別の方法で試してみたことろ編集ができるようになりました。

1.upload_formに記述している中間テーブルのバリデーションを削除し、中間テーブルに記述した

class UploadTagRelation < ApplicationRecord belongs_to :tag belongs_to :upload validates :upload_id validates :tag_id end

上記のように記述してみたがエラーが発生。

ArgumentError in UploadsController#show You need to supply at least one validation

エラー内容を調べてみたところ、バリデーションを下記のように修正する必要があると分かった。

class UploadTagRelation < ApplicationRecord belongs_to :tag belongs_to :upload validate :upload_id validate :tag_id end

2.upload_formのsaveメソッドを修正

def save(tag_list) ActiveRecord::Base.transaction do @upload.update(title: title, text: text, url: url, working_day: working_day, day_off: day_off, cafe_wifi_id: cafe_wifi_id, cafe_charging_id: cafe_charging_id, cafe_smoking_id: cafe_smoking_id, user_id: user_id, image: image) @upload.upload_tag_relations.each do |tag| tag.delete end →@upload.upload_tag_relationをupload_tag_relationsと複数系に修正。 tag_list.each do |tag_name| tag = Tag.where(name: tag_name).first_or_initialize tag.save upload_tag_relation = UploadTagRelation.where(upload_id: upload.id, tag_id: tag.id).first_or_initialize upload_tag_relation.update(upload_id: upload.id, tag_id: tag.id) end end

今回の場合は、formオブジェクトを使用して中間テーブルのバリデーションに誤りがあったため編集、更新、投稿ができない問題が起きていることが分かりました。

ただ、この記述方法でバリデーションが正常に動いているのか少々不安ですが編集ができるようになったのでひとまず安心です。

投稿2021/05/17 12:50

yuu0000

総合スコア4

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

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

0

UploadForm#to_modelにてUploadのインスタンスを返しているため

ruby

1params.require(:upload) #以後省略

になります。

投稿2021/05/15 09:42

asm

総合スコア15149

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

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

yuu0000

2021/05/15 10:24

ご返信ありがとうございます。 こちらの`to_model``を使用した場合には、paramsには同じ記述をする必要があるんですね。 下記のようなエラーが発生してしまったので、こちらの記述にした場合は、コントローラーのeditやupdateのインスタンス変数を修正する必要があるのでしょうか。 ``` NoMethodError in UploadsController#update undefined method `upload_id' for #<UploadForm:0x00007fa8e2235ce8 @upload=#<Upload id: 28, title: "locat", text: "充電ができるカフェ。Wi-Fiも完備。", url: "http:loacal", working_day: "平日10時〜20時", day_off: "水曜日", cafe_wifi_id: 1, cafe_charging_id: 1, cafe_smoking_id: 1, user_id: 1, created_at: "2021-05-14 13:01:39.189558000 +0000", updated_at: "2021-05-14 13:01:39.227136000 +0000">, @title="locat", @text="充電ができるカフェ。Wi-Fiも完備。", @url="http:loacal", @working_day="平日10時〜20時", @day_off="水曜日", @cafe_wifi_id="1", @cafe_charging_id="1", @cafe_smoking_id="2", @image=#<ActionDispatch::Http::UploadedFile:0x00007fa8e2094560 @tempfile=#<Tempfile:/var/folders/gw/k3mqyqh15y37h56g1b17ymvc0000gn/T/RackMultipart20210515-1723-z61inh.png>, @original_filename="アプリ開発で収益を上げる方法アプリ開発で収益を上げる方法.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"upload[image]\"; filename=\"\xE3\x82\xA2\xE3\x83\x95\xE3\x82\x9A\xE3\x83\xAA\xE9\x96\x8B\xE7\x99\xBA\xE3\x81\xA6\xE3\x82\x99\xE5\x8F\x8E\xE7\x9B\x8A\xE3\x82\x92\xE4\xB8\x8A\xE3\x81\x91\xE3\x82\x99\xE3\x82\x8B\xE6\x96\xB9\xE6\xB3\x95\xE3\x82\xA2\xE3\x83\x95\xE3\x82\x9A\xE3\x83\xAA\xE9\x96\x8B\xE7\x99\xBA\xE3\x81\xA6\xE3\x82\x99\xE5\x8F\x8E\xE7\x9B\x8A\xE3\x82\x92\xE4\xB8\x8A\xE3\x81\x91\xE3\x82\x99\xE3\x82\x8B\xE6\x96\xB9\xE6\xB3\x95.png\"\r\nContent-Type: image/png\r\n">, @name="東京, 充電カフェ, 都内", @user_id=1, @validation_context=nil, @errors=#<ActiveModel::Errors:0x00007fa8e222f168 @base=#<UploadForm:0x00007fa8e2235ce8 ...>, @errors=[]>> Did you mean? upload Extracted source (around line #36): 34 35 36 37 38 39 @upload_form = UploadForm.new(upload_params, upload: @upload) tag_list = params[:upload][:name].split(",") if @upload_form.valid? @upload_form.save(tag_list) redirect_to upload_path(@upload.id) else ```
asm

2021/05/15 11:36

> undefined method `upload_id' for #<UploadForm と書かれている通り `upload_id`がvalidateで指定されているのにアクセサが無いことでエラーになっています。 同様にtag_idもアクセサがないのでエラーになるでしょうね。
yuu0000

2021/05/15 12:20

ご指摘頂いた通りアクセサに記述ができておりませんでした、、 下記のように修正してみたところ、エラーは解消できましたが編集した情報が保存されずに編集ページに戻ってしまいます。 attr_accessor :title, :text, :url, :working_day, :day_off, :cafe_wifi_id, :cafe_charging_id, :cafe_smoking_id, :user_id, :image, :name, :upload_id, :tag_id こちらは、formオブジェクト内の記述に誤りがあるのでしょうか、、
asm

2021/05/15 15:42

そうですね。 @upload_idおよび@tag_idがないので、単純にアクセサを定義したところでnilを取得するだけになり 結果、validates :upload_id, presence: trueが満たせずsaveできないのでしょう。 この場合、upload_idおよびtag_idのvalidateは https://guides.rubyonrails.org/active_record_validations.html#custom-methods のようにカスタムメソッドを定義し子要素に丸投げした方がよいでしょうね
yuu0000

2021/05/16 12:33

両者のvalidatesが処理できていないために、取得結果がnillとなりデーターの保存ができないんですね。 カスタムメソッドが初めて聞くものですので、いまいちイメージが掴めないんですが、定義後に子要素に丸投げするとはどのような意味なんでしょうか。
yuu0000

2021/05/17 12:53

カスタムメソッドの実装方法がなかなか難しかったので、formオブジェクトに記述していたバリデーションをupload_tag_relation(中間テーブル)に記述してみたところ編集ができるようになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問