Search code examples
ruby-on-railsflash-message

Rails flash message


I am building an application on Rails where a user creates a Test, goes to the show view for that test and fills in a form with an answer to a question. If the answer to the question matches the "correct_answer" (defined in the controller), there will be flash message that the answer was correct and a button to continue to the root_path will appear. If the answer is wrong, the flash says "Wrong answer."

My problem is that the flash message will say wrong answer even if no answer has been given. I ONLY want that message to appear AFTER the user has submitted the form. I understand why this is happening, I just am unsure about how to fix it. Here is the show view for a test:

<div class="col-md-8 col-md-push-2">
        <h4>Current Score: <%= @test.score %></h4>
        <br /><br />


        <div class="form_group">
        <%= form_tag test_path(@test), :method=> 'get' do %>
            <h4>What is my first name?</h4>
            <div class="form-group">
                <%= text_field_tag :answer, params[:answer], class: 'form-control' %>
            </div>
            <% if !flash[:success] %>
            <div class="form-group">
                <%= submit_tag "Submit", class: "btn btn-primary" %>
            </div>
            <% end %>
        <% end %>
        </div>

        <% if flash[:success] %>
            <%= link_to "Continue", root_path, class: "btn btn-success pull-right" %> 
        <% end %> 
    </div>

Here is the controller for tests, which contains the offending show action:

 class TestsController < ApplicationController

def index 
    @test = Test.new 
    @tests = Test.all
end 

def show 
    @test = Test.find(params[:id])
    correct_answer = "jack"
    user_answer = params[:answer]
    if user_answer == correct_answer
        flash.now[:success] = "That is correct!"
        new_score = @test.score += 1
        @test.update(score: new_score)
    elsif params[:answer] != correct_answer
        flash.now[:danger] = "Wrong answer" 
    end 
end 

def create 
    @test = Test.create(test_params)
    if @test.save 
        redirect_to test_path(@test)
        flash[:success] = "Test created"
    else 
        flash[:danger] = "There was a problem"
        render "index" 
    end 
end 

def destroy 
    @test = Test.find(params[:id])
    if @test.destroy
        flash[:success] = "Your test was removed"
        redirect_to root_path 
    end 
end 

private 

    def test_params
        params.require(:test).permit(:score, :user_id)
    end
end

Is there a better way to do this? If not, can I somehow stop the flash message from appearing on the initial load? I ONLY want it to appear once the form has been submitted. Thanks in advance.


Solution

  • So your flash is triggered because params[:answer] is undefined and not == to jack.

    You say:

    My problem is that the flash message will say wrong answer even if no answer has been given.

    But your logic is off for this outcome, your code says that params[:answer] is defined, which it can't be since the form is not rendered yet.

    Maybe your condition should be:

    elsif params[:answer].present? && params[:answer] != correct_answer
      flash.now[:danger] = "Wrong answer" 
    end 
    

    Traditionally, the showing of the form and POST to a form are separete actions, which is why you're seeing this flash before anything even happens.