Marco
Marco

Reputation: 141

how to run a method multiple times in Rails controller

I'm building a game app, which contains multiple levels. I want my game to proceed to the next level when the user has provided the right answer. At this time, my code is able to move from level 1 to level 2, but once at level 2, it cannot proceed beyond that to level 3. Even when the right answer is provided, the game will not proceed beyond level 2.

Here's my controller code:

class Game1Controller < ApplicationController
    def play
        @game1 = Game1lv.find(params[:level])
        @game1l = Game1lv.where(:level => @game1).limit(1).pluck(:imagelink)
        @game1a = Game1lv.where(:level => @game1).limit(1).pluck(:answer)
        @game1link = @game1l[0].to_s
        @game1answer = @game1a[0].to_s
        @game1answer_user = params["answer"]

        if @game1answer_user == @game1answer
            redirect_to game1_play_path(@game1.level += 1), :flash => { :success => "You are right! Now try the next question" }
        end
    end
end

I tried to use for loop inside my play method, but Rails prompted the error:

Render and/or redirect were called multiple times in this action.

What am I doing wrong, and how can I make it so my users can proceed beyond level 2?

Upvotes: 0

Views: 368

Answers (1)

Michael Gaskill
Michael Gaskill

Reputation: 8042

Try something like this:

def play
  @game1 = Game1lv.find(params[:level])
  @game1link = @game1.imageLink
  @game1answer = @game1.answer

  @game1answer_user = params["answer"]

  if @game1answer_user == @game1answer
    @game1.update({ level: @game2.level + 1 })

    redirect_to game1_play_path(@game1.level), :flash => { :success => "You are right! Now try the next question" }
  end
end

A few improvements have been made. Instead of querying the database individually for each field, the code now extracts those fields from the original query. This is standard ActiveRecord functionality.

Also, the line @game1.update is used to increment the level and save the new level to the database. This is the succinct and preferred version of this code:

@game1.level += 1
@game1.save!

The level has to be saved back to the database after it's incremented, or the increment is lost when the action redirects.

Upvotes: 2

Related Questions