can't get text input to work on my simple Sinatra text numbers game - ruby

I have made a simple game in Ruby to help learn it. Now, I've been trying to implement it in Sinatra, however I cannot get the text input to interact with the 'while' loop. Can anyone help me see what I'm doing wrong?
require 'rubygems'
require 'sinatra'
require 'sinatra/reloader'
require 'haml'
#use Rack::Session::Pool
module HotColdApp
def initialize
guesses = 1
i = rand(10)
end
def play
"Guess a number from 1 to 10"
"You have 5 tries"
"----------"
guess = gets.to_i
while guess != i and guesses < 5
guesses = guesses + 1
if guess < i
"too cold"
guess = gets.to_i
else guess > i
"too hot"
guess = gets.to_i
end
end
if guess == i
"just right"
else
"try again next time"
end
end
end
include HotColdApp
get '/' do
p initialize
haml :index
end
post '/' do
guess = params[:guess]
haml :index, :locals => {:name => guess}
end
__END__
## index
!!!!
%html
%head
%title Hot/Cold
%body
%h1 hOt/cOld
%p
Guess a number from 1 to 10. You have 5 tries.
%form{:action => "/", :method => "POST"}
%p
%input{:type => "textbox", :name => "guess", :class => "text"}
%p
%input{:type => "submit", :value => "GUESS!", :class => "button"}
%p

I'm not sure if this does exactly what you're looking for but it does play the game. Some things to notice: I changed the play method. Using a while loop and gets doesn't really make much sense. Instead I grabbed the parameter and passed to play while keeping count of the guesses. I indented the form because you weren't nesting submit or the text field inside of the form. I recommend you look at the source of your page after you generate with haml. It didn't see that you totally understood what was going on. This should give you more than a few steps to get ahead with.
require 'sinatra'
require 'sinatra/reloader'
require 'haml'
#use Rack::Session::Pool
module HotColdApp
def initialize
#guesses = 5
#i = rand(10)
end
def play(guess)
guess = guess.to_i
if(#i != guess && #guesses > 1)
#guesses -= 1
if guess < #i
return "#{#guesses} left. Too cold"
else guess > #i
return "#{#guesses} left. Too hot"
end
elsif(#i != guess && #guesses == 1)
return "You lose!"
elsif(#i == guess)
return "You win!"
end
end
end
include HotColdApp
get '/' do
p initialize
haml :index
end
post '/' do
guess = params[:guess]
#result = play(guess)
haml :index, :locals => {:name => guess}
end
__END__
## index
!!!!
%html
%head
%title Hot/Cold
%body
%h1 hOt/cOld
%p
Guess a number from 1 to 10. You get 5 tries.
%form{:action => "/", :method => "POST"}
%p
%input{:type => "textbox", :name => "guess", :class => "text"}
%p
%input{:type => "submit", :value => "GUESS!", :class => "button"}
%p
%p= #result

Related

The action 'Search' cannot be found for InboxController

I am trying to add a search bar. I have also set the path. But everytime I try to click on search it directs me to this error. What is the error in this code?
This is my Inbox_Controller file. It says that the action 'Search' cannot be found in InboxController.
class InboxController < ApplicationController
before_action :valid_membership
before_action :change_password_next_login
before_action :agreed_to_terms
before_action :allowed_send_mail?
layout 'inbox'
def bulk
puts params
ids = params[:bulk_ids]
if ids
params[:commit]
case params[:commit]
when 'Archive'
ids.each do |id|
message = Message.find(id)
message.archived = true
message.save()
end
when 'Restore'
ids.each do |id|
message = Message.find(id)
message.archived = false
message.save()
end
else
puts 'invalid action!!'
end
if params[:folder] != ''
redirect_to inbox_index_path(folder: params[:folder])
else
redirect_to inbox_index_path
end
else
flash[:alert] = t('errors.inbox.no_emails_selected')
redirect_to :back
end
end
def index
per_page = 10
page = params[:page] ? params[:page] : 1
#inbox = Inbox.search(params[:search])
case params[:folder]
when 'archive'
#messages = current_user.archived_messages(page, per_page)
when 'drafts'
#messages = current_user.draft_messages(page, per_page)
when 'sent'
#messages = current_user.sent_messages(page, per_page)
else
#messages = current_user.received_messages(page, per_page)
end
end
def reply
original = Message.find(params[:id])
#quoted = "\n\nOn #{original.sent_time.strftime("%m/%d/%y %-I:%M %p")}, # {original.from.full_name} wrote:\n----------------\n#{original.body}"
#message = Message.new(
:parent => original,
:to => original.from,
:subject => "RE: #{original.subject}",
:body => #quoted,
)
render :compose
end
def move
#message = Message.find(params[:id])
folder = params[:destination]
case folder
when 'archive'
#message.archived = true
else
#message.archived = false
end
unless #message.save
puts #message.errors.full_messages
end
redirect_to inbox_index_path(folder: folder)
end
def show
#message = Message.find(params[:id])
if !#message.read? && #message.to == current_user
#message.read_time = DateTime.now
unless #message.save
puts #message.errors.full_messages
end
end
end
def edit
#message = Message.find(params[:id])
#message.to_name = #message.to.full_name
render 'compose'
end
def compose
#message = Message.new
if(params[:id])
#message.to = Mentor.find(params[:id])
end
end
def create
if(params[:message] && !params[:message][:id].empty?)
#message = Message.find(params[:message][:id])
#message.assign_attributes(message_params)
else
#message = Message.new(message_params)
end
if params[:parent_id] && !params[:parent_id].empty?
#message.parent = Message.find(params[:parent_id])
#message.replied_to_time = Time.now
end
#message.from = current_user
draft = params[:draft]
if draft
#message.draft = true
else
#message.sent_time = Time.now
#message.draft = false
end
# puts #message.as_json
if can_send_mail
if #message.save
if !draft
if current_user_or_guest.mentee?
current_user.credits += -1
current_user.save
end
UserMailer.inmail_notification(#message).deliver
end
redirect_to inbox_index_path(folder: draft ? 'drafts' : 'inbox'), notice: "Message successfully #{draft ? 'saved' : 'sent'}."
else
flash.now[:alert] = 'All email fields need to be filled out prior to sending/saving.'
render 'compose'
end
else
flash.now[:alert] = 'You do not have enough credits to send any more InMail to Game Changers.'
render 'compose'
end
ActivityLog.create(userid: current_user.id, points: 500, typeof: "message")
end
def allowed_send_mail?
unless !current_user.admin?
msg = "You are not authorized to access this page!"
show_error(msg)
end
end
def profile_complete
return true if current_user.mentor?
unless current_user.profile_complete?
flash[:alert] = t('errors.inbox.incomplete_profile')
redirect_to edit_user_registration_path
end
end
def message_params
params.require(:message).permit(:id, :to_name, :to_id, :subject, :body)
end
end
This is my relevant index.erb.html file.
<%= form_tag inbox_search_path, :method => 'get' do %>
<p>
<%= search_field_tag :Search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
This is my relevant routes.rb file:
get 'inbox' => 'inbox#index', :as => 'inbox_index'
get 'inbox/show/:id' => 'inbox#show', :as => 'inbox_show'
get 'inbox/compose' => 'inbox#compose', :as => 'inbox_compose'
get 'inbox/compose/:id' => 'inbox#compose', :as => 'inbox_compose_to'
get 'inbox/edit/:id' => 'inbox#edit', :as => 'inbox_edit'
get 'inbox/move' => 'inbox#move', :as => 'inbox_move'
get 'inbox/reply' => 'inbox#reply', :as => 'inbox_reply'
get 'inbox/search' => 'inbox#search', :as => 'inbox_search'
post 'inbox/create' => 'inbox#create'
post 'inbox/bulk' => 'inbox#bulk'
There is no search method in this controller, the only search I see is a call to Inbox.search.
To debug this, start with the view where you actually do the "click". Is that click really supposed to trigger an action in your InboxController? If you think it should, why is there no action in that controller? If not, then the "click" was meant to go to another controller that actually would handle the search action, in which case you need to figure out why the "click" is trying to call a method in your InboxController rather than the desired controller. The problem could be something in your view or something in you routes, or you really should have that method in you InboxController, either way I suggest you try to figure out at least what should be happening and then post some more code stating what you think should be happening vs what is really happening.

Issue with Shoes setup

When i am running shoes.rb file, which contains code to install gem, it throws error.
Undefined method setup for Shoes:Class
Code:
Shoes.setup do
gem 'activerecord' # install AR if not found
require 'active_record'
require 'fileutils'
ActiveRecord::Base.establish_connection(
:adapter => 'postgresql',
:dbfile => 'shoes_app'
)
# create the db if not found
unless File.exist?("shoes_app.sqlite3")
ActiveRecord::Schema.define do
create_table :notes do |t|
t.column :message, :string
end
end
end
end
class ShoesApp < Shoes
require 'note'
url '/', :index
def index
para 'Say something...'
flow do
#note = edit_line
button 'OK' do
Note.new(:message => #note.text).save
#note.text = ''
#result.replace get_notes
end
end
#result = para get_notes
end
def get_notes
messages = []
notes = Note.find(:all, :select => 'message')
notes.each do |foo|
messages << foo.message
end
out = messages.join("n")
end
end
Shoes.app :title => 'Notes', :width => 260, :height => 350
The problem was using Shoes4, where the setup method was unimplemented.
Shoes4 now implements Shoes.setup for backwards compatibility reasons but you don't really need it, so it doesn't do anything except for printing a warning that you should rather do gem install gem_name instead of using Shoes.setup.

Template functions with HAML in Sinatra

I'd like to be able to create template functions in Sinatra HAML templates that themselves contain haml. Is there any way to do this or something similar? It'd be cool if it could work with markdown too.
foo.haml
def foo(x)
%h2 something
%p something about #{x}
%h1 Herp de derp
= foo("mary")
= foo("us")
Cheers!
Actually, you can do something like this:
# app.rb
require 'sinatra'
require 'haml'
helpers do
def foo(name)
haml = <<-HAML
#hello_block
Hello, #{name}
HAML
engine = Haml::Engine.new(haml)
engine.render
end
end
get '/' do
haml :index
end
# index.haml
= foo 'World'
Function is close, what you really need is what's known as a partial. These are predefined templates that you can place inside other views. For instance, you may have a comment partial to display a comment's author, timestamp, content, etc. You can then render this partial for each of the comments on a particular post.
Essentially, you'll end up with the following
# _foo.haml.erb
%h2 somthing
%p= x
# index.haml.erb
%h1 Herp de derp
= render :partial => "foo", :locals => { :x => "mary" }
= render :partial => "foo", :locals => { :x => "us" }

Blocks in pure ERB / Erubis

I have the following Ruby script:
require 'erubis'
def listing(title, attributes={})
"output" + yield + "more output"
end
example = %Q{<% listing "db/migrate/[date]_create_purchases.rb", :id => "ch01_292" do %>
<![CDATA[class CreatePurchases < ActiveRecord::Migration
def change
create_table :purchases do |t|
t.string :name
t.float :cost
t.timestamps
end
end
end]]>
<% end %>}
chapter = Erubis::Eruby.new(example)
p chapter.result(binding)
I am attempting to use a block here and get it to output "output", then the content in the block and then "more output", but I can't seem to get it to work.
I know that ERB used to work this way in Rails 2.3 and now works with <%= in Rails 3... but I'm not using Rails at all. This is just pure ERB.
How can I get it to output all the content?
Jeremy McAnally linked me to this perfect description of how to do it.
Basically, you need to tell ERB to store the output buffer in a variable.
The script ends up looking like this:
require 'erb'
def listing(title, attributes={})
concat %Q{
<example id='#{attributes[:id]}'>
<programlisting>
<title>#{title}</title>}
yield
concat %Q{
</programlisting>
</example>
}
end
def concat(string)
#output.concat(string)
end
example = %Q{<% listing "db/migrate/[date]_create_purchases.rb", :id => "ch01_292" do %>
<![CDATA[class CreatePurchases < ActiveRecord::Migration
def change
create_table :purchases do |t|
t.string :name
t.float :cost
t.timestamps
end
end
end]]>
<% end %>}
chapter = ERB.new(example, nil, nil, "#output")
p chapter.result(binding)
Great. I remember seeing that a while ago. Playing a bit I was getting this:
require 'erubis'
def listing(title, attributes={})
%Q{<%= "output #{yield} more output" %>}
end
example = listing "some title", :id => 50 do
def say_something
"success?"
end
say_something
end
c = Erubis::Eruby.new(example)
p c.evaluate
# => "output success? more output"

Is there a way with test::unit Ruby to load gems

I am trying to use test::unit for testing and the framework I am trying to test requires a particular gem (rhodes)
Can anyone suggest how I can get the gem loaded when I run my tests
Update :: Error Message
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- rho (LoadError)
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
from ../../app/Settings/controller.rb:1
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
from ../test_helper.rb:4
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
from test_settings.rb:4
My unit test uses require to include test_helper.rb which contains following
$: << "../../app"
require 'rubygems'
require 'rhodes'
require 'test/unit'
require 'Settings/controller'
Settings/controller lives in app and contains
require 'rho'
require 'rho/rhocontroller'
require 'rho/rhoerror'
require 'helpers/browser_helper'
class SettingsController < Rho::RhoController
include BrowserHelper
def index
#msg = #params['msg']
render
end
def login
#msg = #params['msg']
render :action => :login, :back => '/app'
end
def login_callback
errCode = #params['error_code'].to_i
if errCode == 0
# run sync if we were successful
WebView.navigate Rho::RhoConfig.options_path
SyncEngine.dosync
else
if errCode == Rho::RhoError::ERR_CUSTOMSYNCSERVER
#msg = #params['error_message']
end
if !#msg || #msg.length == 0
#msg = Rho::RhoError.new(errCode).message
end
WebView.navigate ( url_for :action => :login, :query => {:msg => #msg} )
end
end
def do_login
if #params['login'] and #params['password']
begin
SyncEngine.login(#params['login'], #params['password'], (url_for :action => :login_callback) )
render :action => :wait
rescue Rho::RhoError => e
#msg = e.message
render :action => :login
end
else
#msg = Rho::RhoError.err_message(Rho::RhoError::ERR_UNATHORIZED) unless #msg && #msg.length > 0
render :action => :login
end
end
def logout
SyncEngine.logout
#msg = "You have been logged out."
render :action => :login
end
def reset
render :action => :reset
end
def do_reset
Rhom::Rhom.database_full_reset
SyncEngine.dosync
#msg = "Database has been reset."
redirect :action => :index, :query => {:msg => #msg}
end
def do_sync
SyncEngine.dosync
#msg = "Sync has been triggered."
redirect :action => :index, :query => {:msg => #msg}
end
end
Edit 2: after looking at your code, I believe the following should work:
Move the lines from test_helper
require 'rubygems'
require 'rhodes'
to the very top of Settings/controller
Or are you thinking of loading it dynamically during setup/teardown (possibly to avoid conflicting dependencies etc.)?
Edit: I wrote up a quick example of testing a simple wrapper around a Watir class (UI manipulator for IE browser).
require 'rubygems'
require 'watir'
require 'test/unit'
class WatirWrapper
def initialize()
#browser = Watir::IE.new()
end
def method_missing(sym, *args, &block)
#browser.send(sym, *args, &block)
end
end
class WatirWrapperTest < Test::Unit::TestCase
def test_goto
#ww = WatirWrapper.new()
#ww.goto('http://www.google.com/')
assert_equal('http://www.google.com/', #ww.url())
end
end

Resources