在“show.html.erb”中使用简单表单(嵌套表单)不会将数据保存到数据库
Using simple forms (nested forms) in `show.html.erb` won't save data to database
我一直在尝试在我的 Rails 应用程序中使用嵌套表单或简单表单,特别是在我的 questions/show.html.erb
中,但是当我单击提交时,它会给我一些奇怪的参数。
我的问题有很多答案。我希望能够在问题显示视图中创建答案。
这是我的代码:
问题控制器:
def new
@question = Question.new
@question.answers.build
end
def create
@question = Question.new(question_params)
if @question.save
redirect_to question_path
else
render 'new'
end
end
def show
@question = Question.find(params[:id])
@question.answers.build
end
def edit
@question = Question.find(params[:id])
@question.answers.build
end
def update
@question = Question.find(params[:id])
if @question.update(question_params)
redirect_to question_path
else
render :edit
end
end
def question_params
params.require(:question).permit(:id, :question_title, :question_text, answers_attributes: [ :id, :answer_text, :question_id, :_destroy])
end
AnswersController.rb
def new
@answer = Answer.new
end
def create
@answer = Answer.new(@answer_params)
@answer.question = Question.find(params[:question_id])
@answer.save
respond_to do |format|
format.js
end
end
def edit
@answer = Answer.find(params[:id])
end
def update
@answer = Answer.find(params[:id])
if @answer.update(answers_params)
redirect_to answers_path
else
render :edit
end
end
Question.rb
class Question < ApplicationRecord
belongs_to :topic
belongs_to :user
has_many :answers, dependent: :destroy
accepts_nested_attributes_for :answers, allow_destroy: true
end
Answer.rb
class Answer < ApplicationRecord
belongs_to :question
end
questions/show.html.erb
<div class=question-show>
<div class="question-title"> <%= @question.question_title %></div>
<div class="question_text"> <%= @question.question_text %></div>
<div class="question-user"><%= question_show_timestamp(@question) %> </div>
<div class="question-topic"> <strong>Category:</strong> <%= @question.topic.category.category_name %></div>
<div class="question-topic"> <strong>Topic:</strong> <%= @question.topic.topic_name %></div>
<div class="question-answers">
<%= render "form" %>
<hr>
<% @question.answers.select(&:persisted?).each do |answer| %>
<div>
<div> <%= answer.answer_text %> </div>
<div class="small-font"> <%= answer_timestamp(answer) %> by <%= answer.user.user_name %> </div>
</div>
<hr>
<% end %>
</div>
</div>
_form.html.erb
<%= simple_form_for @question do |form| %>
<div class="TabbedPanelsContent">
<%= form.simple_fields_for(:answers, @question.answers.build) do |builder| %>
<%= render "answer_fields", form: builder %>
<% end %>
<p><%= link_to_add_fields "Add answer", form, :answers %></p>
</div>
<%= form.submit "Save" %>
<% end %>
请注意,我正在使用
simple_fields_for(:answers, @question.answers.build)
如果我把它写成 simple_fields_for :answers,它会为问题的每个答案呈现一个字段,我相信这是因为我在 [=52] 中使用了这个 simple_form =] 查看,但我不完全确定。对此的任何评论都会非常有帮助!
_answer_fields.html.erb
<div class="fields">
<p>
<%= form.input_field :_destroy, as: :hidden %>
<%= link_to "Remove", "#", class: "remove_record" %>
</p>
<p class="lable">Answer</p>
<p class="field"><%= form.text_field :answer_text %></p></br>
</div>
这是我点击保存时发生的情况:
Started PATCH "/questions/19" for 172.18.0.1 at 2018-04-02 13:15:06 +0000
Cannot render console from 172.18.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by QuestionsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"yhLrwHi8wgPRx30ysPakqcKfb+Pjd3BhWN4F/7K5m+FaraCpi7iq6RcrT98q/ISGTv/g8ZlcrDX1ItnrRTBgfQ==", "question"=>{"answers_attributes"=>{"0"=>{"_destroy"=>"false", "answer_text"=>"wer"}}}, "commit"=>"Save", "id"=>"19"}
Question Load (0.8ms) SELECT "questions".* FROM "questions" WHERE "questions"."id" = LIMIT [["id", 19], ["LIMIT", 1]]
(0.4ms) BEGIN
Topic Load (0.8ms) SELECT "topics".* FROM "topics" WHERE "topics"."id" = LIMIT [["id", 1], ["LIMIT", 1]]
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 2], ["LIMIT", 1]]
(0.5ms) ROLLBACK
Rendering questions/edit.html.erb within layouts/application
Rendered questions/edit.html.erb within layouts/application (0.6ms)
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [["id", 2], ["LIMIT", 1]]
Category Load (0.8ms) SELECT "categories".* FROM "categories"
Rendered layouts/_navbar.html.erb (7.2ms)
Rendered questions/_new.html.erb (3.2ms)
Completed 200 OK in 416ms (Views: 392.0ms | ActiveRecord: 4.8ms)
我觉得好笑的那一行是:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"yhLrwHi8wgPRx30ysPakqcKfb+Pjd3BhWN4F/7K5m+FaraCpi7iq6RcrT98q/ISGTv/g8ZlcrDX1ItnrRTBgfQ==", "question"=>{"answers_attributes"=>{"0"=>{"_destroy"=>"false", "answer_text"=>"wer"}}}, "commit"=>"Save", "id"=>"19"}
如你所见,在"answers_attributes" => 那里多了n个“0”。难道我做错了什么?任何建议或帮助将不胜感激。
您觉得该参数行很奇怪,但实际上它是 has_many
关系的嵌套形式的工作方式,所以大多数情况下您都正确地实现了所有内容,但我认为您在这里不需要嵌套形式。
如果您想通过一次请求创建或更新问题以及属于该问题的一个或多个答案,则需要嵌套表单。
在这里你只想创建一个答案,你不想触及问题。所以你可以简化整个事情 - 只为答案创建表格。
questions_controller.rb:
def show
@question = Question.find(params[:id])
@answer = @question.answers.build
end
由于您在 AnswersController
中回复了 js
,我认为您的表单应该是远程的。
questions/show.html.erb:
<div class="question-answers">
<%= simple_form_for @answer, remote: true do |f| %>
<%= f.hidden_field @answer.question_id $>
<%= render 'answers/form_fields', f: f %>
<%= f.submit "Save" %>
</div>
(不要忘记将 question_id
添加到 AnswersController
中允许的参数中)
将用于回答的表单字段移动到 answers
views 文件夹是一件好事。
answers/_form_fields.html.erb:
<div class="fields">
<p class="lable">Answer</p>
<p class="field">
<%= f.text_field :answer_text %>
</p>
</br>
</div>
之后,您应该在提交时在日志中看到下一个(如果您的路由一切正常):
Processing by AnswersController#create
那我会稍微改变一下你的AnswersController
:
def create
@answer = Answer.create(@answer_params)
end
不需要明确设置问题,因为现在你通过params来设置它。如果您只响应一种格式,则无需指定格式。
我一直在尝试在我的 Rails 应用程序中使用嵌套表单或简单表单,特别是在我的 questions/show.html.erb
中,但是当我单击提交时,它会给我一些奇怪的参数。
我的问题有很多答案。我希望能够在问题显示视图中创建答案。
这是我的代码:
问题控制器:
def new
@question = Question.new
@question.answers.build
end
def create
@question = Question.new(question_params)
if @question.save
redirect_to question_path
else
render 'new'
end
end
def show
@question = Question.find(params[:id])
@question.answers.build
end
def edit
@question = Question.find(params[:id])
@question.answers.build
end
def update
@question = Question.find(params[:id])
if @question.update(question_params)
redirect_to question_path
else
render :edit
end
end
def question_params
params.require(:question).permit(:id, :question_title, :question_text, answers_attributes: [ :id, :answer_text, :question_id, :_destroy])
end
AnswersController.rb
def new
@answer = Answer.new
end
def create
@answer = Answer.new(@answer_params)
@answer.question = Question.find(params[:question_id])
@answer.save
respond_to do |format|
format.js
end
end
def edit
@answer = Answer.find(params[:id])
end
def update
@answer = Answer.find(params[:id])
if @answer.update(answers_params)
redirect_to answers_path
else
render :edit
end
end
Question.rb
class Question < ApplicationRecord
belongs_to :topic
belongs_to :user
has_many :answers, dependent: :destroy
accepts_nested_attributes_for :answers, allow_destroy: true
end
Answer.rb
class Answer < ApplicationRecord
belongs_to :question
end
questions/show.html.erb
<div class=question-show>
<div class="question-title"> <%= @question.question_title %></div>
<div class="question_text"> <%= @question.question_text %></div>
<div class="question-user"><%= question_show_timestamp(@question) %> </div>
<div class="question-topic"> <strong>Category:</strong> <%= @question.topic.category.category_name %></div>
<div class="question-topic"> <strong>Topic:</strong> <%= @question.topic.topic_name %></div>
<div class="question-answers">
<%= render "form" %>
<hr>
<% @question.answers.select(&:persisted?).each do |answer| %>
<div>
<div> <%= answer.answer_text %> </div>
<div class="small-font"> <%= answer_timestamp(answer) %> by <%= answer.user.user_name %> </div>
</div>
<hr>
<% end %>
</div>
</div>
_form.html.erb
<%= simple_form_for @question do |form| %>
<div class="TabbedPanelsContent">
<%= form.simple_fields_for(:answers, @question.answers.build) do |builder| %>
<%= render "answer_fields", form: builder %>
<% end %>
<p><%= link_to_add_fields "Add answer", form, :answers %></p>
</div>
<%= form.submit "Save" %>
<% end %>
请注意,我正在使用
simple_fields_for(:answers, @question.answers.build)
如果我把它写成 simple_fields_for :answers,它会为问题的每个答案呈现一个字段,我相信这是因为我在 [=52] 中使用了这个 simple_form =] 查看,但我不完全确定。对此的任何评论都会非常有帮助!
_answer_fields.html.erb
<div class="fields">
<p>
<%= form.input_field :_destroy, as: :hidden %>
<%= link_to "Remove", "#", class: "remove_record" %>
</p>
<p class="lable">Answer</p>
<p class="field"><%= form.text_field :answer_text %></p></br>
</div>
这是我点击保存时发生的情况:
Started PATCH "/questions/19" for 172.18.0.1 at 2018-04-02 13:15:06 +0000
Cannot render console from 172.18.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by QuestionsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"yhLrwHi8wgPRx30ysPakqcKfb+Pjd3BhWN4F/7K5m+FaraCpi7iq6RcrT98q/ISGTv/g8ZlcrDX1ItnrRTBgfQ==", "question"=>{"answers_attributes"=>{"0"=>{"_destroy"=>"false", "answer_text"=>"wer"}}}, "commit"=>"Save", "id"=>"19"}
Question Load (0.8ms) SELECT "questions".* FROM "questions" WHERE "questions"."id" = LIMIT [["id", 19], ["LIMIT", 1]]
(0.4ms) BEGIN
Topic Load (0.8ms) SELECT "topics".* FROM "topics" WHERE "topics"."id" = LIMIT [["id", 1], ["LIMIT", 1]]
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 2], ["LIMIT", 1]]
(0.5ms) ROLLBACK
Rendering questions/edit.html.erb within layouts/application
Rendered questions/edit.html.erb within layouts/application (0.6ms)
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [["id", 2], ["LIMIT", 1]]
Category Load (0.8ms) SELECT "categories".* FROM "categories"
Rendered layouts/_navbar.html.erb (7.2ms)
Rendered questions/_new.html.erb (3.2ms)
Completed 200 OK in 416ms (Views: 392.0ms | ActiveRecord: 4.8ms)
我觉得好笑的那一行是:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"yhLrwHi8wgPRx30ysPakqcKfb+Pjd3BhWN4F/7K5m+FaraCpi7iq6RcrT98q/ISGTv/g8ZlcrDX1ItnrRTBgfQ==", "question"=>{"answers_attributes"=>{"0"=>{"_destroy"=>"false", "answer_text"=>"wer"}}}, "commit"=>"Save", "id"=>"19"}
如你所见,在"answers_attributes" => 那里多了n个“0”。难道我做错了什么?任何建议或帮助将不胜感激。
您觉得该参数行很奇怪,但实际上它是 has_many
关系的嵌套形式的工作方式,所以大多数情况下您都正确地实现了所有内容,但我认为您在这里不需要嵌套形式。
如果您想通过一次请求创建或更新问题以及属于该问题的一个或多个答案,则需要嵌套表单。
在这里你只想创建一个答案,你不想触及问题。所以你可以简化整个事情 - 只为答案创建表格。
questions_controller.rb:
def show
@question = Question.find(params[:id])
@answer = @question.answers.build
end
由于您在 AnswersController
中回复了 js
,我认为您的表单应该是远程的。
questions/show.html.erb:
<div class="question-answers">
<%= simple_form_for @answer, remote: true do |f| %>
<%= f.hidden_field @answer.question_id $>
<%= render 'answers/form_fields', f: f %>
<%= f.submit "Save" %>
</div>
(不要忘记将 question_id
添加到 AnswersController
中允许的参数中)
将用于回答的表单字段移动到 answers
views 文件夹是一件好事。
answers/_form_fields.html.erb:
<div class="fields">
<p class="lable">Answer</p>
<p class="field">
<%= f.text_field :answer_text %>
</p>
</br>
</div>
之后,您应该在提交时在日志中看到下一个(如果您的路由一切正常):
Processing by AnswersController#create
那我会稍微改变一下你的AnswersController
:
def create
@answer = Answer.create(@answer_params)
end
不需要明确设置问题,因为现在你通过params来设置它。如果您只响应一种格式,则无需指定格式。