Rails 5显示仅父资源的上一个或下一个嵌套资源

问题描述 投票:0回答:1

我有一个资源PracticeQuiz,它有一个名为PracticeQuestion的嵌套子。我可以成功创建它们,并且可以转到下一个问题,但我想要的是当用户进行测验时,“上一个”和“下一个”按钮应该只显示父ID中的问题。

例如:

foo.com/practice_quizzes/mountains/practice_questions/1-11,24,25

用户应该可以从问题1-11开始,然后在11处应该转到24,如果用户想要回到11,一旦他们得到问题24,在问题25,它应该不显示按钮或说没有其他问题了。

foo.com/practice_quizzes/fruits/practice_questions/12-23,26,27,31

foo.com/practice_quizzes/animals/practice_questions/28-29,30,32

(请注意,这是关于测验中的问题数量,因为将来会删除或更新或更改问题。我不想基于排序ID,除非这是一个坏主意,我不知道为什么)

我需要的是让用户能够通过单击上一个或下一个来浏览show.html.erb页面,并且只显示与测验相关的问题,无论他们的ID是什么,以及应用程序是当它检测到第一个或最后一个没有问题,或者是否添加了新问题时,不会崩溃。

这是我到目前为止所尝试的:

意见/ practice_question.show.html.erb

<%= link_to 'next', practice_quiz_practice_question_path(@practice_quiz, @practice_question.next) %>

车型/ practice_question.rb

class PracticeQuestion < ApplicationRecord
  belongs_to :user, optional: true
  belongs_to :practice_quiz

  def previous
    PracticeQuestion.where("practice_quiz_id = ? AND id < ?", self.practice_quiz.id, self.id).first
  end

  def next
    PracticeQuestion.where("practice_quiz_id = ? AND id > ?", self.practice_quiz.id, self.id).first
  end

end

车型/ practice_quiz.rb

class PracticeAnswer < ApplicationRecord
  belongs_to :practice_question
end

控制器/ practice_questions_controller.rb

class PracticeQuestionsController < ApplicationController
  before_action :authenticate_user!
  before_action :set_practice_quiz, only: [:show, :edit, :update, :destroy]
  before_action :set_practice_question, only: [:show, :edit, :update, :destroy]

  def index
    if params[:practice_quiz_id]
      @practice_questions = PracticeQuiz.friendly.find(params[:practice_quiz_id]).practice_questions
    else
      @practice_questions = PracticeQuestion.all
    end

    @all_practice_questions = PracticeQuestion.all
  end

  def show
    @current_practice_question = PracticeQuestion.find(params[:id])
  end

  def new
    @practice_quiz = PracticeQuiz.friendly.find(params[:practice_quiz_id])
    @practice_question = PracticeQuestion.new
  end

  def edit
  end

  def create
    @practice_quiz = PracticeQuiz.friendly.find(params[:practice_quiz_id])
    @practice_question = @practice_quiz.practice_questions.build(practice_question_params)
    @practice_question.user = current_user

    respond_to do |format|
      if @practice_question.save
        format.html { redirect_to [@practice_quiz, @practice_question], notice: 'Practice question was successfully created.' }
        format.json { render :show, status: :created, location: @practice_question }
      else
        format.html { render :new }
        format.json { render json: @practice_question.errors, status: :unprocessable_entity }
      end
    end
  end

  private
    def set_practice_question
      @practice_question = PracticeQuestion.find(params[:id])
    end

    def set_practice_quiz
        @practice_quiz = PracticeQuiz.friendly.find(params[:practice_quiz_id])
    end

    def practice_question_params
        params.require(:practice_question).permit(:question, :explanation, :flagged, practice_questions_attributes: [:answer])
     end
end

如何在practice_questions之前/之后执行只显示与其父级id相关的问题?并避免任何错误/陷阱,如达到测验的第一个或最后一个问题?

首先十分感谢 :)

P.S - 有些人说,就控制器/模型/视图而言,这不是一个嵌套资源,但是在我的routes.rb中我这样做了,那么这不是使它成为嵌套资源吗?

  resources :practice_quizzes do 
    resources :practice_questions
  end
ruby-on-rails ruby
1个回答
1
投票

我想象两个选择:

您可以使用测验控制器中的索引获取此测验的所有问题,并使用分页在索引视图中显示它们。如果您将分页设置为每页1个项目,则可以获得您想要的内容。

PracticeQuizzesController

def show
  @quiz = PracticeQuizz.find_by(id: params[:id])
  @questions = @quiz.practice_questions.paginate(:page => params[:page], :per_page => 1)
end

视图/ practice_quizzes / show.html.erb

<%= @quiz.name %>
<%= @quiz.description %>
<%= will_paginate @questions %>
<%= render @questions %>

视图/ practice_questions / _practice_question.html.erb

<%= practice_question.text %>
etc...

第二种选择

在问题的show方法中,获取下一个和上一个问题,以在show视图中显示

练习题控制器

def show
  @question = PracticeQuestion.find_by(id: params[:id])
  @next = @question.practice_quizz.practice_questions.where("id > ?", @question.id).order("id").first
  @prev = @question.practice_quizz.practice_questions.where("id < ?", @question.id).order("id desc").first
end

视图/ practice_questions / show.html.erb

<% if @next %>
  <%= link_to 'next', practice_quiz_practice_question_path(@practice_quiz, @next) %>
<% end %>
© www.soinside.com 2019 - 2024. All rights reserved.