0

I'm trying to make an application to store played FIFA games.

Now I'm already able to make accounts, store games, etc. But when I'm storing a game into the DB, I would also like to store the winner and loser of the game in a way that I can use the count function later to count how many wins or losses a user has.

Controller:

class GamesController < ApplicationController
    before_action :authenticate_user!, exept: [:index, :show]

    def index
        @games = Game.all
    end

    def new
        @game = current_user.games.build
        @user_options = User.all.map{|u| [ u.user_name, u.id ] }
    end

    def create
        @user_options = User.all.map{|u| [ u.user_name, u.id ] }

        @game = Game.new(game_params)
        @game.home_team_user_id = current_user.id

        if @game.home_score > @game.away_score
            @game.winner_id = @game.home_team_user_id
            @game.loser_id = @game.away_team_user_id     
        else if @game.home_score < @game.away_score   
            @game.winner_id = @game.away_team_user_id
            @game.loser_id = @game.home_team_user_id  
        else
        end

        if @game.save
            redirect_to games_path, :notice => "Successfully added game!"
        else
            render 'index'
        end
    end

    def show
        @games = Game.all
    end

    def destroy
        @game = Game.find(params[:id])
        @game.destroy
        redirect_to games_path
    end

    private
    def find_game
        @game = Game.find(params[:id])    
    end

    def game_params
        params.require(:game).permit(:home_team_user_name, :home_score, :away_team_user_name, :away_score, :home_team_user_id, :away_team_user_id, :winner_id, :loser_id)
    end
end
end

View:

<div class="col-md-12" style="text-align:center">
  <div class="panel panel-default" style="margin-right:10px">
    <div class="panel-heading">
      <h3 class="panel-title">Submit New Match</h3>
    </div>
    <div class="panel-body">
      <%= simple_form_for(@game) do |f| %>
      <%= f.text_field :home_score, :placeholder => "Your score" %>
      <%= f.text_field :away_score, :placeholder => "Your Opponents score" %> <br><br>
      <p>Opponent:</p>
      <%= f.select(:away_team_user_id, @user_options) %>
      <br> <br> <%= f.submit "Submit Match", class: "btn-submit" %>
      <% end %>
    </div>
</div>

Is this the correct way to make this calculation? Or do you have other suggestions?

If this is the correct way, then why do I get this error when I try to submit the form:

undefined local variable or method `game_params' for

As you can see in the controller, the game_params is not missing. I've added an end at the end though, because this gave an error to load the form.

2 Answers 2

1

The issue is caused by:

else if @game.home_score < @game.away_score

It should be:

elsif @game.home_score < @game.away_score

Then you can remove one of the last two end

This was causing issues with the method beginnings/endings and conditional beginnings/endings.

Sign up to request clarification or add additional context in comments.

1 Comment

No problem! We've all been there.
0

Models in MVC are responsible for enforcing the business logic. So this calculation should be happening in your model - not in the controller.

class Game < ActiveRecord::Base

  # ...

  belongs_to :winner, class_name: 'User' # or Team or whatever
  belongs_to :loser, class_name: 'User'

  before_validation :evaluate_score!, if: -> { home_score.present? }

  private

    def evaluate_score!
      self.winner = home_score > away_score ? home_team_user : away_team_user
      self.loser = home_score < away_score ? home_team_user : away_team_user
    end
end

Additionally this line is inefficient:

@user_options = User.all.map{|u| [ u.user_name, u.id ] }

Since it pulls the entire records out of the DB and then loops through them in memory. You could use @user_options = User.pluck(:username, :id) but it is not necessary since rails has great helpers for creating inputs from collections:

<%= f.collection_select(:away_team_user, User.all, :id, :user_name) %>

Simple Form has an association helper method which pimps up the Rails collection_* helpers:

<%= f.association :away_team_user, collection: User.all, label_method: :user_name %>

2 Comments

I agree. Nice addition!
Thanks for this, I'll check it out!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.