node.js: boilerplating a site with express.js

Install express globally in your system, so you can use it from anywhere:
$npm install -g express

Initialize your installation:
$express myapp; cd myapp;

Modify your package.json file inside of there, and run it. Here’s a boilerplate example of it:

{
  "name": "nameofyourapphere",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "dependencies": {
    "express": "~3.3.5"
  },
  "author": "",
  "license": "BSD"
}

$npm install // only if you modify the boilerplate generated package.json

You can also save dependencies to your installation file. For example, if you need extra packages, specify the –save option and you will have them

$npm install less-middleware –save

Create a boilerplate using some of the express flags:
$express -s -e -c less -f cli-app
Where:
-s or –sessions adds session support
-e or –ejs adds EJS1 engine support, by default jade2 is used
-J or –jshtml adds JSHTML3 engine support, by default jade is used
-H or –hogan adds hogan.js engine support
-c or –css adds stylesheet support (e.g., LESS4 or Stylus5), by
default plain CSS is used
-f or –force forces app generation on non-empty directory
The directories created with this option are:
1. public for static assets
2. views for templates
3. routes for request handlers

Go to the directory you created with the boilerplate options, and start your app:
$ cd cli-app; npm install; # you have to install again because you have new options after boilerplating
$ node app # your server should start at this point, and you should see the Welcome to Express page

Deploy to heroku
Your root directory needs a Procfile file (no extension), with the following line:
web: node app.js

That will tell Heroku what to run (app.js)

Also, if you are using mongodb, you need to have the following line in your app.js, so Heroku switch to the proper connection:
var host = process.env.MONGOHQ_URL || “mongodb://@127.0.0.1:27017/test”;

You also need to set MONGOHQ plugin on your heroku account. It is free for low traffic.

Also, you have to make your port Heroku friendly, and be able to switch to a known port when you are in your local env, by doing the following (in app.js as well):

var port = process.env.PORT || 3000;

server.listen(port, function() {

console.log(“Server listening on port ” + port + “.”);

});

$git init; git add .
$git commit -am “Initial commit”
$heroku create [your app name]
$git push heroku master
$heroku open

Things to keep in mind

– Variables set with “set” are global to the app now. For example:
app.set(‘appName’,’SomeGenericName’);
and later, in your template, you can read it like:
head
title= appName // Inside a jade file

– To make jsonp work, you need to set the following:
app.set(‘jsonpcallbackname’,’cb’); // So now cb=[your cb function] will be the function used for jsonp

– etags are enabled by default:
app.disable(‘etag’);

Rails: barebones site template from the ground up, version II, using rails 4

Assuming you have rails 4 already running in your system. And git / heroku also ready to go.

$ rails new your-project

Add a bunch of static pages, remove the default page:
remove public/index.html (if there)
$ rails generate controller StaticPages home help about contact_us –no-test-framework
Inside config/routes.rb”
– Comment out the static pages you don’t need, or add the right routes to the ones you want:
# get “contact_us” => “static_pages#contact_us” (example)
– Add a default page as home:
root :to => “static_pages#home”

Add devise, and their views:
Modify your gem file to contain the following lines:
gem ‘devise’
gem ‘sqlite3’, group: [:development, :test]
gem ‘pg’, group: :production

$ bundle install –without production
$ rails generate devise:install # Follow the instructions printed

$ rails generate devise user
$ rake db:migrate
To be able to modify the devise views as any other template:
$ rails generate devise:views

Add source control, push to Heroku
$ git init
$ git add .
$ git commit -am “Initial commit”
$ heroku login # if you haven’t
$ heroku create [name of your app]
$ git push heroku master
$ heroku run rake db:migrate

Static assets

If images and such are not showing on heroku production, you may have to pre compile them locally, using the following command:

RAILS_ENV=production bundle exec rake assets:precompile

This will generate the static assets inside the public directory. Ideally you should use a CDN to serve your images, but this should be ok for small projects.

Extra gems you may need for Rails 4.0

gem ‘rails_12factor’, group: :production

That will take care of any errors related to assest

Rails: Active Record callbacks

There are simple filter-like, provided methods (aspect oriented style), to deal with the life and death cycles of models, the most common are:

  • before_create
  • after_create
  • before_save
  • after_save
  • before_destroy
  • after_destroy

If for any reason, the method returns false, the chain of events will stop, for instance:

def before_create
  false
end

will effectively stop any model creation.

To make things more readable, it is recommended you move your filters to the top of the model, just below the validation section, and list it as:

   after_create :email_article_author
   ...
   def email_article_author
      puts "stuff here..."
   end

This way you can also put multiple methods (comma separated) in the filter.

Rails: model associations

In SQL terms, you associate two tables using a foreign key reference in one, that points to an id on the other.

In rails, the convention is:

#{singular_name_of_parent_class}_id

For example: table articles has comments associated with it, so in the comments table there is an “article_id” column that points the records in there to the ids on the articles table. Once those tables are associated, you can do stuff in rails like this:

article.comments

One to One associations

The example below is establishing an association via the user_id:

rails generate model User email:string password:string

rails generate model Profile user_id:integer name:string birthday:date bio:text color:string twitter:string

To formalize the “marriage”, inside you model you can declare the one to one relationship as follows:

class User < ActiveRecord::Base
has_one :profile
end

class Profile < ActiveRecord::Base belongs_to :user end Once that is setup, you can do stuff like: user.create_profile :name => ‘Jane Doe’, :color => ‘pink’

To create a profile associated with that user

One to many associations

In this example, we are adding the user_id column to an existing “articles” table, via:

rails generate migration add_user_id_to_articles user_id:integer

Once you generate and run your migration, you upgrade your model to be able to handle the one to many relationship:

belongs_to :user # In the article model

has_many :articles # In the user’s model

You could also specify how the records are to be retrieved when calling all articles in a given user:

has_many :articles, -> { order('published_at DESC, title ASC')}

When you are dealing with dependencies, you can also specify what happens if a given record is deleted. For example, if the user’s record is deleted, you can delete all the articles associated with it via internal rails callbacks, by specifying the dependency in the model:

has_many :articles, -> { order(‘published_at DESC, title ASC’)},
:dependent => :destroy

And, that is also the difference between the destroy and the delete methods: the destroy one will call the internal rails callbacks when a record is erased, and follow through erasing the associated records.

Many to many relationships

If two tables have records in both sides associated with many records in the other, this is usually consider a has_and_belongs_to_many relationship. There is usually an extra table in the middle that stores the relationships themselves. If, for example, we have an “articles” and “categories” tables associated this way, rail will usually generate a table in the middle called articles_categories, which will store the ids of both as an association record.

This class of in-between, join table, is special in the sense it doesn’t have a primary key on its own. In this case, the migration file in rails will have something like:

      def change
        create_table :articles_categories, :id=> false do |t|
          t.references :article
          t.references :category
        end
      end

Notice how the :id=>false to avoid creating that.

Important: Not sure if there is a bug in rails, but the migration above produce an articles_categories table, with no columns… I had to manually add them to the schema.db file (definitely a “don’t do it”) to be able to continue. I am still searching for the issue. But be aware of that!

In your category and article models, you will specify the relationship as:

has_and_belongs_to_many :categories
has_and_belongs_to_many :articles

Going further with this, if you have a comment model, which is associated to the articles model, and you want to query all the comments a user has, you have to do that by using the articles model as the join table (or in substitution of it). This is expressed as has_many :through

In this case, you will create some “replies” object, that express the responses (via comments) that a user got in their articles:

has_many :replies, :through => :articles, :source => :comments # at the user's model

So now you have access to queries like:
user.replies.empty?
user.replies.size
user.replies.first
article.comments.create(:name => ‘Guest’, :email => ‘guest@example.com’, :body => ‘Great article!’)

Ruby: CRUD operations

Saving stuff:

article = Article.new # create a new class
article.save # persist the record to DB
Article.count # will give you the number of articles saved in db

# same as save, but it saves to db right away:

Article.create(:title => “some title”, :body => “some more text”, :published_at => ‘2013-01-01’)

Finding stuff:

current_article = Article.find(3) # Find by id
Article.first # Finds the first article
Article.last # Find the last one
all_articles = Article.all # Return them all articles
all_articles.size # The number of records returned
all_articles[3] # gives you the article in position 3
articles = Article.order("published_at") # if you want them in a certain order
Article.where(:title => 'RailsConf').first # Finds the first article with that condition
articles.each { |article| puts article.title } # Print the title of each article

 Deleting stuff

Article.last.destroy # Delete the last article
Article.destroy([2,3]) # Destroy records with id 2 and 3