Link shorthand application in Sinatra - ruby

This was my first Sinatra project - link shortener but I am stuck with some errors and to be honest sinatra's built-in debugger tells me literally nothing. I would like you to give me a clue or suggest a solution to problem.
http://min.us/mkBIVTh7p - screenshot, this happen when I submit my form with url: http://google.com and word google
require 'sinatra'
require 'shotgun'
require 'data_mapper'
require 'dm-migrations'
require 'dm-sqlite-adapter'
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/form.db")
class Url
include DataMapper::Resource
property :id, Serial
property :url, String
property :suggestion, String
end
get '/' do
erb :index
end
post '/' do
Url.create(:url => params[:url], :suggestion=> params[:suggestion])
end
get '/Url.suggestion' do
query = request_path.slice!(0)
redirection = Url.first(:suggestion => query)
redirect redirection.url
end
index.rb
<!doctype html>
<html>
<head>
<title>Skracanie linków</title>
</head>
<body>
<form name="form" method="post" action="#">
<fieldset>
<legend>Wpisz co trzeba</legend>
<p><label> <input type="text" name="post[url]"/>Url:</label></p>
<p><label> <input type="text" name="post[suggestion]"/>Suggested name:</label></p>
</fieldset>
<p class="center">
<input type="reset" value="Wyczyść formularz"/>
<input type="submit" value="Wyślij"/>
</p>
</form>
</body>
</html>

This is because you need to finalize your models. See http://datamapper.org/getting-started.html under the heading "Finalize Models".
Add the finalize command after defining your models:
class Url
include DataMapper::Resource
property :id, Serial
property :url, String
property :suggestion, String
end
# add this line
DataMapper.finalize

Related

How to print to web page using Ruby and Sinatra

I'm calling a ruby function in a post method and I'm trying to output the contents from the function to the web page but it prints the output in my console instead. How do I get it to print to the page?
I've tried
<%=rsg(params[:grammar_file])%> inside an erb file
and
rsg(params[:grammar_file])
inside of the post method and both just print to the console
require 'sinatra'
require 'sinatra/reloader' if development? #gem install sinatra-contrib
require './rsg.rb'
enable :sessions
get '/' do
erb :index
end
post '/' do
rsg(params[:grammar_file])
erb :index
end
<% title = "RANDOM SENTENCE GENERATOR" %>
<!doctype html>
<html lang="en">
<head>
<title><%= #title || "RSG" %></title>
<meta charset="UTF8">
</head>
<body>
<h1>RubyRSG Demo</h1>
<p>Select grammar file to create randomly generated sentence</p>
<form action="/" method="post">
<select name="grammar_file">
<option value="Select" hidden>Select</option>
<option value="Poem">Poem</option>
<option value="Insult">Insult</option>
<option value="Extension-request">Extension-request</option>
<option value="Bond-movie">Bond-movie</option>
</select>
<br><br>
<input type="submit" value="submit">
</form>
<section>
<p>Here</p>
<p><%= rsg(params[:grammar_file])%></p>
</section>
</body>
</html>
You need to tell your template what to do with the params.
This is what is happening:
post '/' do
rsg(params[:grammar_file])
# your rsg method produces some output. I guess you have a line the `puts` your params to stdout somewhere. Instead you should redirect the output into the template.
erb :index
end
Like this:
post '/' do
erb :index, :locals => {:rsg => rsg(params[:grammar_file])}
end
Then, in your :index template you have a line like:
<%=rsg%>
To output the generated String.
The problem might also be that you're tryng to return a puts statement instead of the plain string:
def rsg(p)
puts "I love my daily #{p}. Good luck to you"
end
This will just print to the console and nothing else (true to be precise)
Better:
def rsg(p)
"I love my daily #{p}. Good luck to you"
end
Here you will just return the String from your method and calling rsg("sandwich") will return:
# => "I love my daily sandwich. Good luck to you"

Timeout with ActiveRecord(ActiveRecord::ConnectionTimeoutError )

While creating an application using ActiveRecord with sinatra, I encountered such an error.
    
ActiveRecord::ConnectionTimeoutError at / could not obtain a database
connection within 5.000 seconds (waited 5.005 seconds)
What I was about to do was to "get a profile image from Twitter API, save it in a database, and embed it in index.erb". I stopped here.
The code is below.
main.rb
require "sinatra"
require "sinatra/reloader"
require "twitter"
require "active_record"
ActiveRecord::Base.establish_connection(
adapter: "sqlite3",
database: "./image.db"
)
class Src < ActiveRecord::Base
end
def get_profile_image
#srcs = Src.order("id desc").all
end
def add_profile_image(twitter_id)
client = Twitter::REST::Client.new(
consumer_key: "[CONSUMER_KEY]",
consumer_secret: "[CONSUMER_SECRET]",
access_token: "[ACCESS_TOMEN]",
access_token_secret: "[ACCESS_TOKEN_SECRET]"
)
user = client.user(twitter_id)
url = user.profile_image_url
src = Src.new(account: twitter_id, url: url)
src.save
end
def delete_img(twitter_id)
Src.find_by(account: twitter_id).delete
end
get "/" do
get_profile_image
erb :index
end
post "/" do
add_profile_image(params[:id])
get_profile_image
erb :index
end
get "/delete" do
delete_img(params[:id])
get_profile_image
erb :index
end
index.erb
<form method="post" action="/">
<input type="text" name="id">
<input type="submit" value="enter">
</form>
<form method="get" action="/delete">
<input type="text" name="id">
<input type="submit" value="delete">
</form>
<% #srcs.each do |src| %>
<div id="images-space" style="float: left;" class="imgs">
<img data-id="<%= src.id %>" src="<%= src.url %>">
</div>
<% end %>
DB table name is "srcs" and column is
id integer primary key
account text
url text
This kind of error is the first time for me, but where is the problem?
Decouple the connection to your database from your code in a separate script to test and publish that with the error produced so that we can reproduce the problem, something like
require "active_record"
ActiveRecord::Base.establish_connection(
adapter: "sqlite3",
database: "./image.db"
)
if !ActiveRecord::Base.connection.table_exists?('SRCS')
ActiveRecord::Schema.define do
create_table 'SRCS' do |table|
table.column :account, :string
table.column :url, :string
end
end
end
class Src < ActiveRecord::Base
self.table_name = 'SRCS'
end
p Src.first

Simple search form for my blog with ruby and sinatra

I'm using sequel.
In my app.rb, I wrote
get '/search' do
#post = Post.find(:Title => "%#{params[:query]}%")
erb :'layout'
end
Layout.erb
<form action="/search" method="get">
<input type="text" name="query"/><br />
<input type="submit" />
</form>
<% if #results %>
<table>
<%#results.each do |r|%>
<tr valign="top">
<td><%=r.title%></td>
</tr>
<%end%>
</table>
<% end %>
And to the blog_model.rb in post class this:
def self.search(query)
#where(:title, query) -> This would return an exact match of the query
where("title like ?", "%#{query}%")
end
And I'm getting this :LocalJumpError at /search
no block given (yield).
So what to do or have I done this code correctly ? Thanks in advance.
I guess the problem is the name of erb file, layout.erb.
Sinatra always search for a layout.erb, if you not explicit indicate other layout file, that will handle the page template. This file has the form:
<!doctype html>
<html>
<head>
...
<body>
...
<%= yield %> insert the content here
...
</html>
There are two solutions:
Rename the layout.erb file.
Replace the erb call by: erb :layout, layout: false

Sinatra to-do list tutorial problems

So, I'm new to Ruby/Sinatra, did a bunch of codecademy lessons and the like. I decided until I actually built something, I wouldn't really understand some core concepts.
I found a tutorial for building a to-do list app in Sinatra, and all was fine and good until I got to the edit and delete functionality. I can read and write to/from the database, but whenever I try to edit or delete, it skips straight to "Note not found".
I couldn't figure this out myself, so I asked a developer friend of mine. When I sent him the code, everything worked absolutely fine for him! We tried a couple of different possible fixes, but to no end. I even downloaded the code from the guy's github, just in case there was a random mistake somewhere in my own code, to no avail.
So, I come here asking for some help! Why won't this work!
Clarification: Here's some of the code, where I think the problem may lie. In edit.erb and delete.erb, no matter what it is going to the else statement and sending me to "note not found". It's reading properly from the database, as my homepage can add and show notes.
recall.rb
get '/:id' do
#note = Note.get params[:id]
#title = "Edit note ##{params[:id]}"
erb :edit
end
put '/:id' do
n = Note.get params[:id]
n.content = params[:content]
n.complete = params[:complete] ? 1 : 0
n.updated_at = Time.now
n.save
redirect '/'
end
get '/:id/delete' do
#note = Note.get params[:id]
#title = "Confirm deletion of note ##{params[:id]}"
erb :delete
end
delete '/:id' do
n = Note.get params[:id]
n.destroy!
redirect '/'
end
edit.erb
<% if #note %>
<form action="/<%= #note.id %>" method="post" id="edit">
<input type="hidden" name="_method" value="put">
<textarea name="content"><%= #note.content %></textarea>
<input type="checkbox" name="complete" <%= "checked" if #note.complete %>>
<input type="submit">
</form>
<p>Delete</p>
<% else %>
<p>Note not found.</p>
<% end %>
delete.erb
<% if #note %>
<p>Are you sure you want to delete the following note: <em>"<%= #note.content %>"</em>?</p>
<form action="/<%= #note.id %>" method="post">
<input type="hidden" name="_method" value="delete">
<input type="submit" value="Yes, Delete It!">
Cancel
</form>
<% else %>
<p>Note not found.</p>
<% end %>
Moving the delete-route above the other routes seemed to work for me, which would suggest that the /:id -part in the route definition catches the /delete-part as well. You can see the generated regexps with Sinatra::Application.routes.
Here's a minimal:
require 'rubygems'
require 'sinatra'
require 'dm-core'
require 'dm-migrations'
require 'dm-sweatshop'
# Models
DataMapper.setup(:default, 'sqlite::memory:')
class Note
include DataMapper::Resource
property :id, Serial
property :content, Text, :required => true
property :complete, Boolean, :default => false
property :created_at, DateTime, :default => lambda {Time.now}
property :updated_at, DateTime
before(:save) { attribute_set(:updated_at, Time.now) }
end
DataMapper.finalize.auto_migrate!
# Fixtures
Note.fix {{
:content => /\w+/.gen
}}
100.of { Note.gen }
# Routes
before("/:id") {|id| #note = Note.get id }
get("/:id/delete") {|id| #note = Note.get id; erb :delete }
get("/:id") { erb :edit }
put "/:id" do
#note.attributes = params["note"]
#note.save ? redirect(to("/")) : erb(:edit)
end
delete("/:id") { #note.destroy; redirect(to("/")) }
# Templates
template :layout do
'<!DOCTYPE html>
<html>
<body><%= yield %></body>
</html>'
end
template :edit do
'<% if #note %>
<form action="/<%= #note.id %>" method="POST">
<input type="hidden" name="_method" value="PUT">
<textarea name="note[content]"><%= #note.content %></textarea>
<input type="checkbox" name="note[complete]"
<%= #note.complete? && "checked" %> >
<input type="submit">
</form>
<p>Delete</p>
<% else %>
<p>Note not found.</p>
<% end %>'
end
template :delete do
'<% if #note %>
<p>Are you sure you want to delete the following note:
<em>"<%= #note.content %>"</em>?</p>
<form action="/<%= #note.id %>" method="POST">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="Yes, Delete it!">
Cancel
</form>
<% else %>
<p>Note not found</p>
<% end %>'
end
I don't know if this is still interesting someone, but a simple
params[:id].to_i
fixed it for me.

Simple Search With Datamapper and Sinatra

I'm fairly new to Ruby and backend development in general. That being said I'm trying to create a simple search form. I'm using Sinatra as the framework and Datamapper as my ORM. What is the best way to do this? Below is my schema I would like the search action to search both the tile and category.
require 'sinatra'
require 'datamapper'
DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/cal.db")
class Event
include DataMapper::Resource
property :id, Serial
property :title, String
property :text, Text
property :contact_name, String
property :contact_email, String
property :location, String
property :event_start_time, String
property :event_end_time, String
property :category, String
property :created_at, DateTime
property :approved, Boolean, :default => false
end
DataMapper.auto_upgrade!
post '/search' do
#results = Event.all
erb :layout
end
============
layout.erb
<form action="/search" method="post">
<input type="text" name="query"/><br />
<input type="submit" />
</form>
<% if #results %>
<table>
<%#results.each do |r|%>
<tr valign="top">
<td><%=r.title%></td>
</tr>
<%end%>
</table>
<% end %>
The most basic search query could like this:
#events = Event.all(:title.like => "%#{params[:query]}%") | Event.all(:category.like => "%#{params[:query]}%")

Resources