You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 5自定义资源prev/next方法放哪?MCQ标签筛选单题展示

Hey there! Let's tackle your two Rails questions with practical, convention-aligned solutions:

1. Should custom previous/next methods go in the controller or model in Rails 5?

Short answer: Stick them in the model.

Rails leans hard into the MVC pattern, where models own data and business logic, while controllers handle request routing, data coordination, and response rendering. Your previous/next behavior is about querying related records (finding the prior/next MCQ in a sequence) — this is core data logic that belongs in the model.

Putting these methods in the model also makes them reusable across different controllers or contexts, keeps your controllers lean and focused, and makes testing way easier (you can validate the logic independently of HTTP requests).

2. How to filter MCQs by tag and enable sequential viewing?

Since you're already using acts_as_taggable, you get a built-in tagged_with method to filter records by tag. We’ll combine that with custom model logic for sequential navigation, then wire everything up in the controller.

Step 1: Add sequential navigation methods to your model

First, add methods to the MultipleChoiceQuestion model to fetch the previous/next MCQ with the same tag. This keeps your controller clean and follows the "fat model, skinny controller" principle:

class MultipleChoiceQuestion < ApplicationRecord
  acts_as_taggable

  # Find the previous MCQ matching the specified tag
  def previous_in_tag(tag_name)
    self.class.tagged_with(tag_name)
            .where("id < ?", self.id)
            .order(id: :desc)
            .first
  end

  # Find the next MCQ matching the specified tag
  def next_in_tag(tag_name)
    self.class.tagged_with(tag_name)
            .where("id > ?", self.id)
            .order(id: :asc)
            .first
  end
end

Step 2: Update your controller to handle tag filtering

Modify the show action in your MultipleChoiceQuestionsController to accept a tag parameter, fetch the current MCQ, and use the model methods to get navigation targets:

class MultipleChoiceQuestionsController < ApplicationController
  def show
    @mcq = MultipleChoiceQuestion.find(params[:id])
    @current_tag = params[:tag]

    # Only load navigation links if a tag is provided
    if @current_tag.present?
      @previous_mcq = @mcq.previous_in_tag(@current_tag)
      @next_mcq = @mcq.next_in_tag(@current_tag)
    end
  end
end

In your show.html.erb (or equivalent view file), add links to let users navigate between tagged MCQs:

<div class="question-navigation">
  <% if @previous_mcq %>
    <%= link_to "← Previous Question", mcq_path(@previous_mcq, tag: @current_tag) %>
  <% end %>

  <% if @next_mcq %>
    <%= link_to "Next Question →", mcq_path(@next_mcq, tag: @current_tag) %>
  <% end %>
</div>

Quick notes:

  • If you want to sort by something other than id (like created_at), just adjust the order clause in the model methods.
  • The tagged_with method does exact matches by default. If you need fuzzy matching (MCQs with any matching tag), use tagged_with(tag_name, any: true).
  • For a better user flow, add an index action that lists all MCQs for a specific tag, linking directly to the first question in the sequence.

内容的提问来源于stack exchange,提问作者mazing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:41:17