📜 ⬆️ ⬇️

Lightweight Ruby Web Applications

Rapid development


Inspired by posts on Western blogs like Clone TinyURL with 40 lines of Ruby or Clone Pastie in 15 Minutes with Sinatra & DataMapper , I decided to try to go through and describe the whole process of implementing a lightweight web application on Ruby from design to deployment.



Instruments


Ruby has a huge number of different tools for quick development. I stopped at the following:
')
Sinatra - DSL for the web. Lightweight framework operating according to the “convention over configuration” principle. It allows you to quickly and easily develop web applications, and is easily complemented by everything you need. The basis of our application.

DataMapper - ORM, the main competitor of ActiveRecord. In some way inferior, in something superior to the above, works great with different databases, easily configurable and embedded.

HAML - HTML for programmers. Markup language, slightly more beautiful than traditional erb, generates clean and valid xhtml. Contains the equivalent for CSS - SASS .

Heroku - Allows you to conveniently and even for free (of course, with restrictions) to place the resulting application. Optional tool, you can deploy anywhere.

What are we going to write?


Choosing the tools, I thought, and what, exactly, to write? And I decided that it would be a tool for organizing my comic strip. In such an application, there is a client functionality, and an admin panel, and the generation of rss feed for a subscription, which will allow you to touch on different aspects of the development, and bring it closer to real tasks. Well, I also love web comics :)

Parsing code


Here we come to the most interesting. Virtually all of the resulting code is easily understood and can be found on github . I recommend to open it in order to present the big picture, and I would like to dwell on the most important code fragments, and those fragments that caused me some difficulties in implementation.

First, let's analyze the structure of the project, it is very simple:
comics.rb
config.ru
models.rb
public
views


The models.rb file contains models, database configuration and everything related to working with it. comics.rb contains all the code for Sinatra. Also, by default, Sinatra picks up the views folders containing views in haml and public with files accessible from the web (javascript, images).

Let's start with the models.
models.rb
  1. DataMapper. setup ( :default , ENV [ 'DATABASE_URL' ] || "sqlite3:///#{Dir.pwd}/comics.db" )

The database parameters for heroku are contained in ENV ['DATABASE_URL'], if there is no such variable, then create the sqlite database in the project directory. There is nothing to edit in the source.

models.rb
  1. class DateTime
  2. def rfc822
  3. self . strftime "% a,% d% b% Y% H:% M:% S% z"
  4. end
  5. end

The RSS 2.0 specification requires a date in RFC # 822 format. To do this, add the rfc822 method to the DateTime class objects, which will format the timestamp as needed, and we will use it later in the views.

comics.rb
  1. def protected!
  2. response [ 'WWW-Authenticate' ] = % ( Basic ) and \
  3. throw ( : halt , [ 401 , "Not authorized ] ) and \
  4. return unless authorized?
  5. end
  6. def authorized?
  7. comics = Comics. first
  8. @auth || = Rack :: Auth :: Basic :: Request . new ( request. env )
  9. @auth . provided ? && @auth . basic ? && @auth . credentials && @auth . credentials == [ comics. login , comics. password ]
  10. end

A simple implementation of authentication for Sinatra. Almost entirely taken from the FAQ , the difference is that the username and password are taken from the database, instead of embedded in the source. The use is extremely simple: just enter the protected action in need of authentication !

comics.rb
  1. get '/rss.xml' do
  2. content_type 'application / rss + xml' ,: charset => 'utf-8'
  3. @comics = Comics. first
  4. @strips = Strip. all : limit => 10
  5. haml ( : rss ,: layout => false )
  6. end

Return rss feed. Change the Content-Type, and add: layout => false to prevent the feed from being rendered to layout.

Now a few hints in the views.
layout.haml
  1. % title = "#{@comics.title} - #@@strip.title}" rescue @comics . title

If you do not use the exception mechanism here, then with an empty @strip variable, the NoMethodError error will stop us, since the nil class does not have a title method. In the cut such things should always be kept in my head.

models.rb
  1. class Strip
  2. # declare property
  3. def next
  4. Strip. first ( : created_at . gt => self . created_at,: order => [ : created_at . asc ] )
  5. end
  6. def previous
  7. Strip. first ( : created_at . lt => self . created_at )
  8. end
  9. def get_id
  10. self . id
  11. end
  12. default_scope ( : default ) . update ( : order => [ : created_at . desc ] )
  13. end

layout.haml
  1. - tonext = "/#{@strip.next.get_id}" rescue "#"
  2. - toprevious = "/#{@strip.previous.get_id}" rescue "#"

The mechanism is clear - search for the next and previous strip for the one that we are looking at now, and displaying links to them in the view. Why it was necessary to do a separate get_id method instead of directly using an existing id ? The fact is that if we watch the last strip for the current moment, then the next method will return nil . And nil in turn has an id method, which I think will return “4” for a long time. You can see for yourself by experimenting in irb.

On this with analysis you can and finish, I will be happy to answer any questions about the code, and respond to criticism in the comments.

Deployment


The written application can be easily launched like any other application on the synatra using the ruby comics.rb command . But we want to show it to the world, and Heroku will help us in this. We register on heroku, and install gem heroku on our local machine. Now we write the config for Rack:
config.ru
  1. require 'comics'
  2. run Sinatra :: Application

The next step is to create an application on heroku, and push the code there. Let's agree that the application is already in your git repository:
heroku create comics
git push heroku master

It remains only to fill the database with initial data. For this purpose, there is an install method in models.rb :
heroku console
install

That's all, you can go to the address that issued the gem when creating the application, and if everything is done correctly, then enjoy the result.

Links


Comics on github
Heroku demo ( admin , password on request in habraposhta).

Source: https://habr.com/ru/post/67267/


All Articles