Simple Search With Datamapper and Sinatra - ruby

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]}%")

Related

Add usernames to database

I have this line in an .erb file to get the input of the username
<input type="text" placeholder="User Name" name="user[username]" value="<%#{#user.username}%>" class="form-control">
for my User.rb class I have the following:
class User
include DataMapper::Resource
property :id, Serial
property :username, String
property :password, String
property :role, String
end
DataMapper.finalize()
get '/users' do
#users = User.all
erb :users
Within users.erb I have the following
<div class="container">
<h3>Users</h3>
<% if #users.any? %>
<ul <%#users%>>
<% #users.each do |user|%>
<li><%#{user.username}%></li>
<%end%>
<%else%>
<p>No Users in database</p>
<%end%>
</ul>
</div>
I want the to login a user and have that username stored in the database and then display that on the users page but it just keeps getting the else statement and I don't know why

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

Link shorthand application in Sinatra

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

Sinatra/Carrierwave: how to update a record while using an existing image?

My super-simple Sinatra app is a list of notes, and each note has an attached image.
I've got a 'put' route set up that lets me update notes, but unless I re-upload the image, I lose it (note.image is set to 'nil' when I submit the form).
Thanks in advance for your help!
Here's my uploader:
class MyUploader < CarrierWave::Uploader::Base
include CarrierWave::MimeTypes
process :set_content_type
storage :fog
end
Here's my Note class:
class Note
include DataMapper::Resource
property :id, Serial
property :image, String, :auto_validation => false
property :content, Text, :required => true
property :created_at, Date
property :updated_at, Date
mount_uploader :image, MyUploader
end
Here's my 'put' route:
put '/:id' do
n = Note.get params[:id]
unless n
redirect '/', :error => "Can't find that note."
end
n.image = params[:image]
n.credit = params[:content]
n.date = params[:date]
n.updated_at = Time.now
if n.save
redirect '/', :notice => 'Note updated successfully.'
else
redirect '/', :error => 'Error updating note.'
end
end
And here's the form I'm using to update notes:
<% if #note %>
<form action="/<%= #note.id %>" method="post" id="edit" enctype="multipart/form-data">
<input type="hidden" name="_method" value="put">
<p><input type="text" name="credit" value="<%=h #note.content %>"></p>
<p><input type="file" name="image" /></p>
<br><br>
<input type="submit">
</form>
<% else %>
<p>Note not found.</p>
<% end %>
A simple if check is what you need: if params[image] is nil you skip the n.image = params[:image]
n.image = params[:image] if params[:image]
I use similar approach to create a custom Rails validation check when I work with ActiveRecord models that contain CarrierWave images. Probably it won't be a bad idea to check whether or not n.image isn't nil as well - if it's nil I guess it should be mandatory to upload an image.

Datamapper update enum value through form

I have a model like this:
class Project
include DataMapper::Resource
property :id, Serial
property :title, String
property :slug, String
property :status, Enum[:open, :closed ], :default => :open
has n, :issues
end
I've created a view to update the project status:
<form action="/project/update" method="post" id="project">
<label for="status">Status
<select id="status">
<option value="0"
<% if(#project.status == :open) %>
selected="selected"
<% end %>
>Open</option>
<option value="1"
<% if(#project.status == :closed) %>
selected="selected"
<% end %>
>Closed</option>
</select>
</label>
</form>
Here's the route:
post '/project/update' do
#project = Project.get(params[:project_id])
#project.update(:title => params[:title])
end
What values does the form need to pass to the route to update the status? and what should the route look like in this instance?
Thanks,
"open" and "closed" - they will be converted to symbols automatically.

Resources