Я пытаюсь добавить вспомогательную _form моей модели комментариев в представление рекламы. Звоню помощнику <%= render 'comments/form', comment: @comment %> по маршруту /advertisement/:id
Итак, вот мой комментарии _form:
<%= form_with(model: comment, local: true, url: "/comments") do |form| %>
<% if comment && comment.errors.any? %>
<div id = "error_explanation">
<h2><%= pluralize(comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% comment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class = "form-group">
<%= form.label :content %>
<%= form.text_area :content, class:"form-field" %>
</div>
<%= form.hidden_field :advertisment_id, value:params[:id] %>
<div class = "actions">
<%= form.submit "Envoyer", class:"btn btn-primary", url: 'comments' %>
</div>
<% end %>
Я указываю url: "/comments", потому что я нахожусь в /advertisment/:id, и по умолчанию действие направлено сюда.
Но когда сообщение дошло до моего контроллера комментариев, он не смог прочитать параметры.
ActionController::ParameterMissing in CommentsController#create
Странно то, что у меня есть доступ к параметрам:
{"utf8"=>"✓", "authenticity_token"=>"0+swOqHPEHN2Gwh0TO3iC7VPRz4ROLoBlkaMkOdnjjYxWHoDer7AwrgnQpu+9VHfSY90yMSRsNp8ojvPJxuzmQ= = ", "content"=>"Test", "advertisment_id"=>"1", "commit"=>"Envoyer"}
Итак, вот комментарий контроллер:
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
# [...]
# POST /comments
# POST /comments.json
def create
@comment = Comment.new(comment_params.merge(:user_id => @session_user.id))
respond_to do |format|
if @comment.save
format.html { redirect_to @comment, notice: 'Comment was successfully created.' }
format.json { render :show, status: :created, location: @comment }
else
format.html { render :new }
format.json { render json: @comment.errors, status: :unprocessable_entity }
end
end
end
# [...]
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
@comment = Comment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:content, :advertisment_id)
end
end
Спасибо большое за вашу помощь





Согласно документам здесь, если вы укажете опцию url в form_with без опции scope, полученные параметры будут отсутствовать в названии prefixes. Следовательно
params.require(:comment).permit(:content, :advertisment_id)
вызовет ошибку, поскольку параметры не включают comment.
Вам следует удалить опцию url из вашего form_with или использовать опции url и scope одновременно.
Рад, что это помогло, я был бы более чем счастлив получить положительный голос.
Я сделал ... но вам придется подождать, пока у меня будет 15 репутации, чтобы увидеть мой голос за!
Вероятно, это потому, что ваш @comment - это nil, поэтому form_with работает как старый помощник form_tag.
Используя form_with, поле типа <%= form.text_field :content %>
<input type = "text" name = "comment[content]" /><input type = "text" name = "content" />.Во втором случае ваша сильная проверка параметров отклонит голые параметры.
Чтобы решить эту проблему, просто назначьте действующую модель вашему render.
<%= render 'comments/form', comment: Comment.new %>
Спасибо, что решение отлично работает. У меня один вопрос по модели, потому что когда я ставлю <%= render 'comments/form', comment: @comment %>, я отдаю своему form_with модель. Так почему же он будет генерировать params[:content], а не params[:comment][:content], как это было при указании класса?
a model означает экземпляр объекта модели нацеливания. Только когда вы даете модель, form_with присваивает объем этой модели. В вашем случае, поскольку @comment - это nil, поэтому form_with не знает области действия, поэтому генерируются голые параметры.
Большое спасибо, это действительно было отсутствие
scopeна моемform_with. Я скучаю по этой части, поэтому<%= form_with(model: comment, local: true, scope: :comment, url: "/comments") do |form| %>работают отлично.