※rails初心者です。何か誤りなどがあればご指摘下さい。
ユーザーが投稿フォームで送信した値以外のキーもストロングパラメーターを介して取得したい。
グループチャット機能のあるwebアプリケーションを開発中です。現在ビューでユーザーが投稿フォームに入力したメッセージ若しくは画像ファイルをテーブルに保存するという機能を実装しています。
app/views/messages/_footer.html.haml
.footer
= form_for [@group, @message] do |f|
= f.text_field :body
= f.file_field :image
= f.submit "SEND"
⚠︎見易くするために記述を簡略化しています。
app/controllers/messages_controller.rb
class MessagesController < ApplicationController
before_action :authenticate_user!
def index
@messages = Message.find(params[:group_id])
@group = Group.find(params[:group_id])
@message = Message.new
end
def create
@message = Message.new(message_params)
if @message.save
redirect_to group_messages_path(params[:group_id]), notice: "メッセージ送信成功"
else
flash.now[:alert] = "メッセェ〜ジを入力してください!"
render "index"
end
end
private
def message_params
end
end
app/models/message.rb
class Message < ApplicationRecord
belongs_to :user
belongs_to :group
validates :group_id, presence: true
validates :user_id, presence: true
validates :body_or_image, presence: true
private
def body_or_image
body.presence or image.presence
end
end`
ユーザーの投稿時に、メッセージ本文も画像もない投稿がされるのを避けるため(何も入力されていない状態で送信ボタンを押すと空のレコードが保存されてしまう。)どちらか一方がないと保存されないようにバリデーションをかけます。さらに送信された値がどのグループのどのユーザーが送信したものなのか識別できる必要があるのでgroup_idとuser_idとの両方にそれぞれバリデーションをかけます。しかしここで問題が発生。送信された値をストロングパラメーターを介して保存したいのですが、基本的にパラメーターは入力された値のキーしか持たないのです。つまりgroup_idとuser_idの2つはパラメーターのキーとして存在しないのです。(この2つはユーザーが投稿フォームに入力する値ではないので。)なので
app/controllers/messages_controller.rb
~省略~
private
def message_params
binding.pry
params.require(:message).permit(:body, :image, :user_id, :group_id)
end
↑こう書きたいですけど機能しません。
そこで使うのがmergeメソッドです。このメソッドを使うことでパラメーターに新たなキーを統合することができます。
app/controllers/messages_controller.rb
~省略~
private
def message_params
binding.pry
params.require(:message).permit(:body, :image).merge(user_id: current_user.id, group_id: params[:group_id])
end
↑このように記述することで、ユーザーが投稿フォームで送信する2つのキーを持ったパラメーターに新たなキーを加えることができます。そして投稿フォームに入力しない値もストロングパラメーターを介して保存できるようになります。めでたしめでたし。