Table of Contents
- The First Build
- The Project Now
- CSS & JavaScript
- Challenges
- Heroku Deployment & Establishing A Connection To The Database
Flatiron School Experience
I attended Flatiron School from November 2019 to May 2020. It was one of the most amazing experiences I've ever had. Students have to build an application in each of the program's five modules. I was in the fast-paced program, so each module lasted a month long. The first month was about learning Procedural and Object-Oriented Programming with Ruby.
In this blog, I will show you the difference from when I first created a Sinatra application with Flatiron, to what it looks like now after the Bootcamp.
Flatiron Month 2
The second month of Flatiron began a new module with Sinatra. It is a free and open-source software web application library and domain-specific language(DSL) written in Ruby. Sinatra is what Flatiron first introduces you to in order to learn web applications.
Building a Sinatra Web Application
The first build
I wanted to build an application where users could spread awareness about "Hole in the Wall" types of stores. The first build did exactly that.
The "home" page:
The reviews#new form page:
Nothing really special. It was a barebones build. The application would CRUD reviews
, but wouldn't CRUD stores
or favorites
. Users could signup and login, but couldn't delete or edit their account.
The Project Now
The application could have way more features than it does right now. I don't know how to design the website better without feedback, and some very great friends took their time to tell me some things they wish were implemented. When I update the CSS, I will also update this blog on what features I added.
You can view the live application here at: https://hole--in-the--wall.herokuapp.com/
Users can now signup and login. They can also edit or delete their account.
Stores can now be created & linked to Google Maps as well as edited.
Reviews can now be created, edited, and deleted.
Favorites of stores can now be created and deleted.
The application now features semantic HTML.
Using "Wave" Google Chrome extension
This awesome extension allows you to view the current status of accessibility on your web page.
CSS
I used Flexbox on pages where the layout was more simple.
I used Media Queries to make sure breakpoints were set in place.
JavaScript
I implemented Javascript into pages where I wanted forms to appear when a user clicked a certain button, instead of having to create more views with erb
.
I didn't want to fetch
information in this application. I just wanted to keep straight as Sinatra backend/frontend application using erb
views. The only Javascript necessary was to shorten up how many views templates there were.
Challenges
The challenges in upgrading this application involved: Heroku deployment, Sinatra gems, ActiveRecord Queries, Javascript, and CSS.
For example, the Sinatra Contrib gem's Namespace feature wouldn't function with the application as it interferes with Rack's namespace. Sinatra just released their newest update, so I might update the namespace feature in the near future.
Flatiron teaches the basics of ActiveRecord but it's up to you to figure out how it really works. Updating this application let me review and deal with things like ActiveRecord method chaining, ActiveRecord::Relation, ActiveRecord::Result, grabbing or converting query return values, security, and eager loading.
Heroku won't allow SQLite3 when you deploy your website. I provisioned a PostgreSQL database for my application from Heroku instead.
SQLite3 and PostgreSQL won't allow some of the same types of queries. For example in SQLite3, this worked:
Store.select(
"stores.id,
stores.name,
stores.state,
count(favorites.store_id) AS favorites_count"
).joins(:favorites).limit(5).group(:name).order(
"favorites_count DESC"
).as_json
But it wouldn't work in PostgreSQL, as you need to group the column names together outside of the aggregate in the .group
method.
Store.select(
"stores.id,
stores.name,
stores.state,
count(favorites.store_id) AS favorites_count"
).joins(:favorites).limit(5).group(
"stores.id,
stores.name,
stores.state"
).order("favorites_count DESC").as_json
Heroku Deployment
When configuring my environment to establish a connection to the database, the only blogs and articles available for doing so with ActiveRecord featured establishing the connection directly to ActiveRecord itself, like this example:
require 'bundler/setup'
Bundler.require
configure :development do
ENV['SINATRA_ENV'] ||= "development"
require 'bundler/setup'
Bundler.require(:default, ENV['SINATRA_ENV'])
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => "db/#{ENV['SINATRA_ENV']}.sqlite"
)
end
configure :production do
db = URI.parse(ENV['DATABASE_URL'] || 'postgres:///localhost/mydb')
ActiveRecord::Base.establish_connection(
:adapter => db.scheme == 'postgres' ? 'postgresql' : db.scheme,
:host => db.host,
:username => db.user,
:password => db.password,
:database => db.path[1..-1],
:encoding => 'utf8'
)
end
This was also taught at Flatiron. It's good to know, but for this application, there actually is a much simpler way of establishing a connection to your database.
If you go to the sinatra-activerecord github page, it will tell you that all you need to do is this:
"Require the 'sinatra/activerecord' gem in your Sinatra application, and establish the database connection:"
# app.rb
require "sinatra/activerecord"
set :database, {adapter: "sqlite3", database: "foo.sqlite3"}
# or set :database_file, "path/to/database.yml"
"If you have a config/database.yml
file, it will automatically be loaded, no need to specify it. Also, in production, the $DATABASE_URL
environment variable will automatically be read as the database (if you haven't specified otherwise)."
So this is literally what my environment.rb looks like:
require 'bundler/setup'
Bundler.require
require_all 'app'
Then in my application_controller
:
configure do
set :public_folder, 'public'
set :views, 'app/views'
set :database_file, "config/database.yml"
enable :sessions
end
configure :test, :development do
set :session_secret, File.read("config/keys/session_secret.txt")
set :google_api, File.read("config/keys/API_KEY.txt")
end
configure :production do
set :session_secret, ENV['SESSION_KEY']
set :google_api, ENV['GOOGLE_API_KEY']
end
All I had to do was specify where my database.yml
file was, and it configured the connection to the database for me.
The Sinatra Readme also talks about configuration settings using the configure
method above.
Heroku allows you to set environment variables for your application as well. You can find out here.
Heroku also requires that you include a Procfile in the root level of your application, that specifies what commands to run when starting the application. For this app I only included:
web: bundle exec rackup config.ru -p $PORT
Feedback
I greatly appreciate that you took the time to read this blog and viewed what my application can do. If you would like to take a look through the code and see if there are any improvements that could be made I would be very grateful.
I will add features/fixes to the application when I can. If you have something you'd like to add, feel free to push it to Github. :)
- Reach out to me on Twitter
- Contribute to the hole-in-the-wall Github repo
This is an application I love and would love to keep using. I will update this application using different frameworks and tools to run and develop it more smoothly.
Top comments (0)