Home Rails 5 shuffle resource attributes on page load
Reply: 2

Rails 5 shuffle resource attributes on page load

mazing
1#
mazing Published in 2018-02-14 05:22:37Z

In my views/practice_questionx/index.html.erb file, I want to shuffle certain attributes of the model from the database on each page load. I know I have to get the attributes into an array and call a .shuffle method on them, but I am really struggling with the syntax and how to do that.

views/practice_questions/index.html.erb

<% @practice_questions.each do |practice_question| %>

 ...

<p class="main-practice-question-answer">
  <%= practice_question.answer_choice_one %> 
</p>

<p class="main-practice-question-answer">
  <%= practice_question.answer_choice_two %> 
</p>

<p class="main-practice-question-answer">
  <%= practice_question.answer_choice_three %> 
</p>

<p class="main-practice-question-answer">
  <%= practice_question.answer_choice_four %> 
</p>

<p class="main-practice-question-answer">
  <%= practice_question.answer_choice_five %> 
</p>

controllers/practice_questions_contoller.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]

    @practice_questions = PracticeQuiz.all.friendly.find(params[:practice_quiz_id]).practice_questions.order('created_at ASC').paginate(:page => params[:page], per_page: 1)
    # first get the practicequiz with its friendly id, passing it its real id, then get all the pracice questions, then paginate it?


  def show
  @question = PracticeQuestion.find_by(id: params[:id])
  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

# Never trust parameters from the scary internet, only allow the white list through.
def practice_question_params
  params.require(:practice_question).permit(:question, :explanation, :flagged, :answer_choice_one, :answer_choice_two, :answer_choice_three, :answer_choice_four, :answer_choice_five, :answer_choice_correct)
end

end

schema

 create_table "practice_questions", force: :cascade do |t|
    t.text "question"
    t.text "explanation"
    t.boolean "flagged"
    t.string "user_id"
    t.bigint "practice_quiz_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.text "answer_choice_one"
    t.text "answer_choice_two"
    t.text "answer_choice_three"
    t.text "answer_choice_four"
    t.text "answer_choice_five"
    t.text "answer_choice_correct"
    t.index ["practice_quiz_id"], name: "index_practice_questions_on_practice_quiz_id"
  end

Ultimately, I want to shuffle just the five answer choices on each page load, so they show in a random order each time. I've been trying to figure it out for hours and just can't seem to understand how to do it.

Josh McMillan
2#
Josh McMillan Reply to 2018-02-14 05:41:23Z

With your current database schema the easiest way to do this would be to load your answers into their own array, shuffle that array and then iterate through it:

<%
  answer_choices = %w(one two three four five).map { |number| practice_question.public_send("answer_choice_#{number}") }.shuffle
  answer_choices.each do |choice|
%>
  <p class="main-practice-question-answer">
    <%= choice %> 
  </p>
<% end %>

Here's what the code is doing:

  • First, it builds up an array of "one", "two", "three", "four", "five" using Ruby's percent string syntax
  • It then calls #map on that array, converting "one", "two", "three" etc into the answer choice for that given number. It does this by calling #public_send on the practice_question object, which is a convenient way of calling a method that you need to build the name for
  • It then calls #shuffle on the result, which randomly orders our questions
  • We can then iterate through our array of random answer choices, printing out each choice as we go. Hurrah!
marmeladze
3#
marmeladze Reply to 2018-02-14 05:36:20Z

Not the best solution, but might save your day.

In your model,

def answers
  [
    answer_choice_one, answer_choice_two, 
    answer_choice_three, answer_choice_four, 
    answer_choice_five
  ].shuffle
end

And on your view,

<% practice_question.answers.each do |answer| %>
  <p class="main-practice-question-answer">
    <%= answer %> 
  </p>
<% end %>
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.302336 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO