2015-11-17 2 views
1

Итак, я все еще Rails noob, поэтому я могу полностью ошибиться, но у меня есть два контроллера. Контроллер вопросов и контроллер ответов. Я пытаюсь создать функцию оценки, которая позволяет пользователю администратора назначать вопросы для эссе. Я использую /answer/:id, где: id - это идентификатор вопроса, а затем рендеринг частичного итерации всех ответов для этого идентификатора. Ясно, как грязь Я уверен ...Проблема маршрутизации после обновления

Моя проблема: в частичном, где отображается ответ пользователя, у меня есть форма, которая позволяет администратору заполнить количество баллов для этого ответа и отправить. В идеале я хотел бы перейти на следующую страницу (используя will_paginate), но, как минимум, я хотел бы остаться на одной странице. Я могу получить форму, но она продолжает идти/отвечает /: 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

Я не 100% ясно по этому вопросу, но '<% = form_for ответа, удаленный: истинные do | f | %> 'может быть то, что вы ищете, это предотвратит ссылку на новый URL-адрес. –

ответ

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 

Тогда вам придется создать приложение/просмотров/ответы/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», поэтому вы можете использовать обновление и показать в своем первоначальном виде (для обновления и ответа или отображения ответа), если потребуется позже в вашем проекте.

+0

Отлично! Я попытаюсь попробовать это, как только я очищу некоторые другие вещи. Мне нравится идея проходить через страницы, так как каждый отправляет оценку, поэтому, надеюсь, это сработает! Еще раз спасибо. – Prkl8r

+0

OK, дайте мне знать, как это происходит ... – hec

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 это идентификатор индивидуального ответа, поэтому не то, что я надеюсь

Средство для этого является следующим:

#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 
+0

Я внес некоторые из ваших предложенных изменений. Я продолжаю работать в «неопределенном методе« разрешение »для ошибки« 1 »: String в предложении params.require. Я не могу понять. Хеш params, похоже, содержит всю информацию, необходимую для создания объекта класса. Я также попытался изменить ввод класса на число, поскольку я настроил его как целое. – Prkl8r

+0

Параметры: { "utf8" => "✓", "_method" => "положить", " authenticity_token" => "8UhJhKm9V6Mejxfm2uMpTPTP + 4eGhxzfwpgJyc9k9afOG61iy/BjLPwJJUeiFFNMXqBOS3 + 2axlno/fbWagq + А ==", «graded_by "=>" 1 ", " answer_id "=>" 20 ", " grade "=>" 1 ", " commit "=>" Submit Grade ", " question_id "=>" 1 ", " ID "=>" 20" } – Prkl8r