dimanche 29 avril 2018

Rails - passing randomly generated instance variable between routes

I'm creating an app which randomly displays a "flashcard" for language practice, which the user needs to provide a translation to. I have two tables: Flashcards (containing the flashcard data) and Practices (for managing the practice sessions and storing the responses provided).

I have managed to get a flashcard to randomly display when the user starts a practice session but what I can't work out is how to set the code so that when a user provides the response, the program remembers/knows which random card has been displayed so it can correctly POST to Practices. My current code generates a new card between showing the card and saving it to the database as @flashcard doesn't persist between routes.

# practices_controller.rb

def index
  call_random
end

def create
  call_random
  @practice = Practice.create(practice_params.merge(session_id: @session_id, flashcard_id: @flashcard.id))
  if @practice.save
    redirect_to @practice
  else
    render 'index'
  end
end

def show
end

private

def find_practice
  @practice = Practice.find(params[:id])
end

def random_flashcard
  @flashcard = Flashcard.order("RANDOM()").first
end

def call_random
  @flashcard ||= random_flashcard
end

I've tried setting and reading class attributes and other private methods to try and save the randomly generated flashcard (either the whole object or the ID) but no solution has worked for me. One methods which I thought might get me close was this, but it still failed as @flashcards was still nil in the create route.

# practice_controller.rb

def index
  random_flashcard(:generate)
end

def create
  random_flashcard(:recall)
  @practice = Practice.create(practice_params.merge(session_id: @session_id, flashcard_id: @flashcard.id))
  if @practice.save
    redirect_to @practice
  else
    render 'index'
  end
end

private

def random_flashcard(action = :generate)
  if action == :generate
    @flashcard = Flashcard.order("RANDOM()").first
  elsif action == :recall
    @flashcard
  end
end




Aucun commentaire:

Enregistrer un commentaire