所以我仍然是一个Rails noob,所以我可能完全没错,但我有两个控制器。问题控制器和答案控制器。我正在尝试构建一个评分功能,允许管理员用户为论文问题分配点数。我正在使用/answer/:id
:id是问题的id,然后渲染部分迭代该id的所有答案。清楚如泥,我敢肯定......
我的问题:在显示用户答案的部分内容中,我有一个表单,允许管理员填写该答案的分数并提交。理想情况下,我希望它移动到下一页(使用will_paginate),但至少,我想留在同一页面上。我能够使表单工作,但它继续到/ answers /:id,但其中:id是单个答案的id,所以不是我希望的。
answers_controller.rb
class AnswersController < ApplicationController
def index
@user = current_user
@questions = Question.all
end
def show
@user = current_user
@question = Question.find(params[:id])
@answers = Answer.where("question_id = ?", @question.id).paginate(:page => params[:page], :per_page => 1)
@answer = Answer.where("question_id =? AND user_id = ?", @question.id, @user.id)
end
def edit
@answer = Answer.find(params[:id])
end
def update
@answer = Answer.find(params[:id])
if @answer.update_attributes(grade_params)
flash[:success] = "Answer Graded"
else
flash[:warning] = "Not Graded"
end
end
private
def grade_params
params.require(:answer).permit(:points_earned)
end
end
_essay_grades.html.erb(在包含表单的节目页面上呈现的部分内容)
<% @answers.each do |answer| %>
<p>User: <%= answer.user_id %></p>
<%= answer.answer %><br>
<%= @question.value %>
<br>
<%= form_for(answer) do |f| %>
<%#= f.radio_button :points_earned, @question.value %><br>
<%#= f.radio_button :points_earned, 0 %> <br>
<%= f.text_field :points_earned %> Points<br>
<br>
<%= f.submit "Award Points" %>
<% end %>
<% end %>
<br>
<br>
<%= will_paginate @answers, renderer: BootstrapPagination::Rails %>
的routes.rb
Rails.application.routes.draw do
resources :admins, :answers, :static_pages, :questions
devise_for :users, :controllers => { registrations: 'registrations' },
:path => '', :path_names =>
{ :sign_in => "login", :sign_up => "register" }
root "static_pages#index"
end
我确信这里有一个简单的解决方案(或者它可能会改变我设置的方式......)。任何帮助是极大的赞赏!
反馈后 添加了成绩模型并建立了与问题的直接关系。
answer_controller.rb
class AnswersController < ApplicationController
def show
@user = current_user
@question = Question.find(params[:id])
@answers = Answer.where("question_id = ?", @question.id).paginate(:page => params[:page], :per_page => 1)
@answer = Answer.where("question_id =? AND user_id = ?", @question.id, @user.id)
end
def update
@user = current_user
@question = Question.find(params[:question_id])
@answer = @question.answers.find(params[:id])
@grade = @question.grades.new(grade_params)
if @grade.save
flash[:success] = "Answer Graded"
redirect_to @question
end
end
private
def grade_params
params.require(:grade).permit(:user_id, :answer_id, :points_earned, :graded_by, :comment)
end
end
_answer.html.erb
<%= answer.user_id %>
<%= form_tag [@question, answer], method: :put do %>
<%= hidden_field_tag :graded_by, current_user.id %>
<%= hidden_field_tag :answer_id, answer.id %>
<%= number_field_tag :points_earned %>
<%= submit_tag "Submit Grade" %>
<% end %>
的routes.rb
Rails.application.routes.draw do
resources :questions do
resources :answers, only: [:update]
end
resources :admins, :static_pages
问题/ show.html.erb
...
<h3>Show answers</h3>
<%= render @answers, locals: {question: @question} %>
<%= will_paginate @answers, renderer: BootstrapPagination::Rails %>
答案 0 :(得分:0)
您必须在表单中使用以下内容,以便更新不会加载新页面,但仍会提交更新。使用Chrome / Firefox开发人员工具查看请求/响应。
<%= form_for(answer), :remote => true do |f| %>
然后,更改答案控制器中的更新操作以加载“下一个未评级的答案”:
def update
rated_answer = Answer.find(params[:id])
if rated_answer.update_attributes(grade_params)
flash[:success] = "Answer Graded"
else
flash[:warning] = "Not Graded"
end
@answer = get_next_unrated_answer(rated_answer.question_id)
end
private
def get_next_unrated_answer(question_id)
# I am making a couple of assumptions on your model here, but get an answer that has not been rated yet for this question
next_answer = Answer.where("question_id = ? and points_earned = ?", question.id, nil)
#returned automatically
end
然后您必须创建app / views / answers / update.js.erb以使用以下行加载页面的新答案:
$('#main_div').html('<%= escape_javascript(render partial: 'whatever_partial_you_have_created_to_display_the_next_unrated_answer') %>');
只需创建一个新的部分,即可显示您的答案并正确填写下一个未评级的答案。或者理想情况下,使用相关的部分加载您的初始“show.html.erb”并重复使用它们。
这是一种简单的方法,但如果我是你,我可能会将这些新功能重命名为不使用'更新'或'显示',而是将其称为'rate',甚至是'rate_show',所以你如果您的项目稍后需要,可以使用更新并以原始形式显示(用于更新和回答或显示答案)。
答案 1 :(得分:0)
根据我对你的问题的理解,我认为你最好调查nested routes
:
#config/routes.rb
resources :questions do
resources :answers, only: [:update]
end
#app/controllers/questions_controller.rb
class QuestionsController < ApplicationController
def show
@question = Question.find params[:id]
end
end
#app/views/questions/show.html.erb
<%= @question.title %>
<%= render @question.answers, locals: {question: @question} %>
#app/views/questions/_answer.html.erb
<%= answer.title %>
<%= form_tag [question, answer], method: :put do %>
<%= text_field_tag :grade %>
<%= submit_tag %>
<% end %>
以上内容将为您提供已经存在的内容(只是为了澄清您的“明显疯狂”的评论并非所有的情况!)。
-
以下是嵌套资源的来源。
目前,似乎您在回答问题时遇到了问题:
其中
:id
是个别答案的ID,所以不是我希望的
对此的补救措施如下:
#app/controllers/answers_controller.rb
class AnswersController < ApplicationController
def update
@question = Question.find params[:question_id]
@answer = @question.answers.find params[:id]
@grade = @answer.grades.new grade_params
redirect_to @question if @grade.save
end
private
def grade_params
params.permit(:points_earned) #-> will probably have to refactor this
end
end
这将为该特定答案创建一个新的grade
(您应该在关联的模型中有)。由于答案已与question
相关联,因此它允许您使用嵌套路由加载两者。
就您的设置而言,我个人会添加Grade
模型,以便您可以为每个答案分配多个成绩。这违反了您当前的架构,但可以很好地确保您具备促进多个等级所需的功能:
#app/models/grade.rb
class Grade < ActiveRecord::Base
belongs_to :answer
belongs_to :user
end
#app/models/answer.rb
class Answer < ActiveRecord::Base
has_many :grades
end