Big_Bird
Big_Bird

Reputation: 427

Accessing variables from different controllers

I'm trying to build a game where you guess numbers. The problem is if you make a mistake it redirects you to a leaderboard(mvc) form where you enter your name plus it`s pre populated with sessions data from a different controller(game) and submits both into the DB.

@round & @points are the two variables I want to access and store as score and level.

class ApplicationController < ActionController::Base


  before_filter :set_current_account

  def set_current_account
    #  set @current_account from session data here
    Game.current = @round
  end   


  protect_from_forgery

end

-

class Leaderboard < ActiveRecord::Base
    cattr_accessor :current
end

# == Schema Information
#
# Table name: leaderboards
#
#  id         :integer         not null, primary key
#  name       :string(255)
#  score      :string(255)
#  level      :string(255)
#  created_at :datetime
#  updated_at :datetime
#

-

class GameController < ApplicationController

  def index
    @games = Game.all
    respond_to do |format|
      format.html 
    end
  end

  def start_game
    session[:round] ||= 1
    session[:points] ||= 0
    @round = session[:round]
    @points = session[:points] 
  end


  def generate_round
    numbers = Array.new(6){rand(9)}
    @addition = []
    @display = numbers
    numbers.inject do |s, i|
        @addition << s + i
        @addition.last
    end
  end

  def next_round
    session[:round] += 1
    session[:points] += 1200
    @round = session[:round]
    @points = session[:points]
  end

  def destroy_sessions
    session[:round] = nil
    session[:points] = nil
    session[:addition] = nil
    @round = session[:round]
    @points = session[:points]
    @addition = session[:addition]
    start_game
  end

  def submit_name
    @game = Game.new(params[:game])

    respond_to do |format|
      if @game.save
        format.html { redirect_to(leaderboard_path, :notice => 'Score was added successfully.') }
      else
        format.html { render :action => "new" }
      end
    end
  end

  def game_over
    redirect_to :controller => 'leaderboards', :action => 'new' and return
  end

Upvotes: 0

Views: 2279

Answers (2)

Ryan Her
Ryan Her

Reputation: 1117

I haven't read the whole thing, but if you just want to access those variables, you can just pass them as parameters.

  1. Pass those values into game_over as params

  2. Use this to redirect

redirect_to :controller => 'leaderboards', :action => 'new' and return, :round => params[:round], :points => params[:points]

Alternatively, you can just keep the session until a new game is started or score is recorded to the leaderboard.

Upvotes: 1

tadman
tadman

Reputation: 211740

I think you've taken an approach here that shouldn't even work. The Rails MVC framework is structured around the principle that each request is serviced independently, and that, in theory, there is no state transfer from one request to the next except through params passed in, records stored in the database and the persistent user session.

To design a web-based application like you might a single-process, single-user, single-session program is a mistake. Using singletons, like your cattr_accessor called current will be problematic since it is both shared between requests, and not shared between different instances of Rails, of which there are typically many.

Mapping more closely to the REST standard of index, new, create, show, edit, update and destroy would help. For instance start_game should be create and destroy_sessions should probably be destroy.

It's not clear from your design if each game is shared amongst several users, or if it they are created for each user individually, so it's hard to say more about how to solve your problem.

Upvotes: 0

Related Questions