Reputation: 19
I have an .erb
file that displays the following lines:
<% if flash[:message]%>
<p><span class"error"><%= flash[:message] %></p>
<%end%>
I would like to set the variable flash[:message]
in a .rb
file and am not sure how to do so. For whatever reason symbols in Ruby tend to confuse me a bit. They seem like pointers, but somewhat different.
File 1:
class HangpersonGame
attr_accessor :word
attr_accessor :guesses
attr_accessor :wrong_guesses
# add the necessary class methods, attributes, etc. here
# to make the tests in spec/hangperson_game_spec.rb pass.
# Get a word from remote "random word" service
# def initialize()
# end
def initialize(word)
@word = word
@guesses = ""
@wrong_guesses = ""
end
def guess(letter)
# make sure the letter is actually a letter
if letter == nil || !(letter.class == String && letter =~ /^[A-z]$/i)
raise ArgumentError
end
# handle different cases
letter.downcase!
# handle repeated guesses
if @guesses.include?(letter) || @wrong_guesses.include?(letter)
flash[message] = "You have already used that letter"
return false
end
#handle case where guess is not a letter
return false if letter.length != 1
# finally handle check and return true
if @word.include? letter
@guesses << letter
else
@wrong_guesses << letter
end
return true
end
def word_with_guesses
result = ''
@word.split('').each do |char|
if @guesses.include? char
result << char
else
result << '-'
end
end
return result
end
def check_win_or_lose
if word_with_guesses.downcase == @word.downcase
return :win
elsif @wrong_guesses.length >= 7
return :lose
else
return :play
end
end
# You can test it by running $ bundle exec irb -I. -r app.rb
# And then in the irb: irb(main):001:0> HangpersonGame.get_random_word
# => "cooking" <-- some random word
def self.get_random_word
require 'uri'
require 'net/http'
uri = URI('http://watchout4snakes.com/wo4snakes/Random/RandomWord')
Net::HTTP.new('watchout4snakes.com').start { |http|
return http.post(uri, "").body
}
end
end
File 2:
<h2>Guess a letter</h2>
<% if flash[:message] %>
<p>
<span class="error"><%= flash[:message] %></span>
</p>
<% end %>
<p>
Wrong Guesses:
<span class="guesses"><%= @game.wrong_guesses %></span>
</p>
<p>
Word so far:
<span class="word"><%= @game.word_with_guesses %></span>
</p>
<form action="/guess" method="post">
<input type="text" size="1" name="guess" autocomplete="off"/>
<input type="submit" value="Guess!"/>
</form>
<%= erb :new %>
File 3:
require 'sinatra/base'
require 'sinatra/flash'
require './lib/hangperson_game.rb'
class HangpersonApp < Sinatra::Base
enable :sessions
register Sinatra::Flash
before do
@game = session[:game] || HangpersonGame.new('')
end
after do
session[:game] = @game
end
# These two routes are good examples of Sinatra syntax
# to help you with the rest of the assignment
get '/' do
redirect '/new'
end
get '/new' do
erb :new
end
post '/create' do
# NOTE: don't change next line - it's needed by autograder!
word = params[:word] || HangpersonGame.get_random_word
# NOTE: don't change previous line - it's needed by autograder!
@game = HangpersonGame.new(word)
redirect '/show'
end
# Use existing methods in HangpersonGame to process a guess.
# If a guess is repeated, set flash[:message] to "You have already used that letter."
# If a guess is invalid, set flash[:message] to "Invalid guess."
post '/guess' do
letter = params[:guess].to_s[0]
### YOUR CODE HERE ###
@game.guess(letter);
redirect '/show'
end
# Everytime a guess is made, we should eventually end up at this route.
# Use existing methods in HangpersonGame to check if player has
# won, lost, or neither, and take the appropriate action.
# Notice that the show.erb template expects to use the instance variables
# wrong_guesses and word_with_guesses from @game.
get '/show' do
### YOUR CODE HERE ###
erb :show # You may change/remove this line
end
get '/win' do
### YOUR CODE HERE ###
erb :win # You may change/remove this line
end
get '/lose' do
### YOUR CODE HERE ###
erb :lose # You may change/remove this line
end
end
Upvotes: 0
Views: 775
Reputation: 3005
You tagged the question as ruby-on-rails, but it is sinatra. In ruby-on-rails you set the flash message in the controller (it's part of the session). You cannot set it in the model.
I don't know how Sinatra works, but I read it's similar. I found this:
You can set the flash message in the controller (post '/guess'):
result = @game.guess(letter);
if result == REPEATED then
session[:message] = "You have already used that letter"
elsif result == WRONG
session[:message] = "Invalid guess"
else
session[:message] = nil
end
This requires you to change the guess method to return different values instead of just true or false.
Then you can set a variable in the controller (get '/show') to be used in the view. I don't know if this is mandatory (or you could use the session[:message] in the view):
@message = session[:message]
session[:message] = nil
Finally you show the message in the show view
<% if @message %>
<p>
<span class="error"><%= @message %></span>
</p>
<% end %>
Upvotes: 1