Ruby on Rails Parsing JSON

Ruby on Rails Parsing JSON

Sometime you have to deal with parsing out JSON. Luckily, this is very easy in any recent version of Ruby. Given the string below:

1
2
3
4
5
6
{
  "products": [{
    "name": "Mac Pro",
    "price": "2500"
  }]
}

You can easily parse this string by using:

1
2
require 'json'
h = JSON.parse(string)

In the above code, it will return a ruby hash that mimics the JSON structure. This means that you can do stuff like this:

1
h["products"][0]["name"] # => "Mac Pro"

So far so good, that’s it! See ya! :)

What Does Gemfile.lock File Use for in Ruby on Rails?

What does Gemfile.lock File use for in Ruby on Rails?

You have noticed a file called Gemfile.lock in your Ruby on Rails application and have wondered what is it, how it works. The file may have even given you trouble when you attempted to push changes to source control. In this article I will discuss what exactly this Gemfile.lock file is and how it helps your Ruby on Rails application.

Gemfile.lock
If you actually opened the Gemfile.lock file you probably saw a bunch of text as below:

Gemfile.lock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
GEM
  remote: https://rubygems.org/
  specs:
    actionmailer (4.0.2)
      actionpack (= 4.0.2)
      mail (~> 2.5.4)
    actionpack (4.0.2)
      activesupport (= 4.0.2)
      builder (~> 3.1.0)
      erubis (~> 2.7.0)
      rack (~> 1.5.2)
      rack-test (~> 0.6.2)
    activemodel (4.0.2)
      activesupport (= 4.0.2)
      builder (~> 3.1.0)
    activenavbar (1.0.0)
    activerecord (4.0.2)
      activemodel (= 4.0.2)
      activerecord-deprecated_finders (~> 1.0.2)
      activesupport (= 4.0.2)
      arel (~> 4.0.0)
    activerecord-deprecated_finders (1.0.3)
    activesupport (4.0.2)
      i18n (~> 0.6, >= 0.6.4)
      minitest (~> 4.2)
      multi_json (~> 1.3)
      thread_safe (~> 0.1)
      tzinfo (~> 0.3.37)
    arel (4.0.2)
    atomic (1.1.16)
    bootstrap-sass (3.0.3.0)
      sass (~> 3.2)
    builder (3.1.4)
    capybara (2.2.1)
      mime-types (>= 1.16)
      nokogiri (>= 1.3.3)
      rack (>= 1.0.0)
      rack-test (>= 0.5.4)
      xpath (~> 2.0)
    coderay (1.1.0)
    coffee-rails (4.0.1)
      coffee-script (>= 2.2.0)
      railties (>= 4.0.0, < 5.0)
    coffee-script (2.2.0)
      coffee-script-source
      execjs
    coffee-script-source (1.7.0)
    columnize (0.3.6)
    database_cleaner (0.9.1)
    debugger (1.6.6)
      columnize (>= 0.3.1)
      debugger-linecache (~> 1.2.0)
      debugger-ruby_core_source (~> 1.3.2)
    debugger-linecache (1.2.0)
    debugger-ruby_core_source (1.3.2)
    diff-lcs (1.2.5)
    erubis (2.7.0)
    execjs (2.0.2)
    factory_girl (4.2.0)
      activesupport (>= 3.0.0)
    factory_girl_rails (4.2.1)
      factory_girl (~> 4.2.0)
      railties (>= 3.0.0)
    haml (3.1.8)
    haml-rails (0.3.5)
      actionpack (>= 3.1, < 4.1)
      activesupport (>= 3.1, < 4.1)
      haml (~> 3.1)
      railties (>= 3.1, < 4.1)
    hike (1.2.3)
    i18n (0.6.9)
    jbuilder (1.5.3)
      activesupport (>= 3.0.0)
      multi_json (>= 1.2.0)
    jquery-rails (3.1.0)
      railties (>= 3.0, < 5.0)
      thor (>= 0.14, < 2.0)
    json (1.8.1)
    mail (2.5.4)
      mime-types (~> 1.16)
      treetop (~> 1.4.8)
    method_source (0.8.2)
    mime-types (1.25.1)
    mini_portile (0.5.2)
    minitest (4.7.5)
    multi_json (1.9.0)
    mysql2 (0.3.15)
    nokogiri (1.6.1)
      mini_portile (~> 0.5.0)
    olive (0.0.1)
    polyglot (0.3.4)
    pry (0.9.12.6)
      coderay (~> 1.0)
      method_source (~> 0.8)
      slop (~> 3.4)
    pry-debugger (0.2.2)
      debugger (~> 1.3)
      pry (~> 0.9.10)
    quiet_assets (1.0.2)
      railties (>= 3.1, < 5.0)
    rack (1.5.2)
    rack-test (0.6.2)
      rack (>= 1.0)
    rails (4.0.2)
      actionmailer (= 4.0.2)
      actionpack (= 4.0.2)
      activerecord (= 4.0.2)
      activesupport (= 4.0.2)
      bundler (>= 1.3.0, < 2.0)
      railties (= 4.0.2)
      sprockets-rails (~> 2.0.0)
    railties (4.0.2)
      actionpack (= 4.0.2)
      activesupport (= 4.0.2)
      rake (>= 0.8.7)
      thor (>= 0.18.1, < 2.0)
    rake (10.1.1)
    rdoc (4.1.1)
      json (~> 1.4)
    rspec-core (2.14.8)
    rspec-expectations (2.14.5)
      diff-lcs (>= 1.1.3, < 2.0)
    rspec-mocks (2.14.6)
    rspec-rails (2.14.1)
      actionpack (>= 3.0)
      activemodel (>= 3.0)
      activesupport (>= 3.0)
      railties (>= 3.0)
      rspec-core (~> 2.14.0)
      rspec-expectations (~> 2.14.0)
      rspec-mocks (~> 2.14.0)
    sass (3.2.15)
    sass-rails (4.0.2)
      railties (>= 4.0.0, < 5.0)
      sass (~> 3.2.0)
      sprockets (~> 2.8, <= 2.11.0)
      sprockets-rails (~> 2.0.0)
    sdoc (0.4.0)
      json (~> 1.8)
      rdoc (~> 4.0, < 5.0)
    shoulda-matchers (2.2.0)
      activesupport (>= 3.0.0)
    slop (3.5.0)
    sprockets (2.11.0)
      hike (~> 1.2)
      multi_json (~> 1.0)
      rack (~> 1.0)
      tilt (~> 1.1, != 1.3.0)
    sprockets-rails (2.0.1)
      actionpack (>= 3.0)
      activesupport (>= 3.0)
      sprockets (~> 2.8)
    thor (0.18.1)
    thread_safe (0.2.0)
      atomic (>= 1.1.7, < 2)
    tilt (1.4.1)
    treetop (1.4.15)
      polyglot
      polyglot (>= 0.3.1)
    turbolinks (2.2.1)
      coffee-rails
    tzinfo (0.3.39)
    uglifier (2.5.0)
      execjs (>= 0.3.0)
      json (>= 1.8.0)
    xpath (2.0.0)
      nokogiri (~> 1.3)

PLATFORMS
  ruby

DEPENDENCIES
  activenavbar (~> 1.0.0)
  bootstrap-sass (~> 3.0.3.0)
  capybara (~> 2.2.1)
  coffee-rails (~> 4.0.0)
  database_cleaner (~> 0.9.1)
  factory_girl_rails (= 4.2.1)
  haml-rails (~> 0.3.4)
  jbuilder (~> 1.2)
  jquery-rails
  json (~> 1.8.1)
  mysql2
  olive (~> 0.0.1)
  pry
  pry-debugger
  quiet_assets
  rails (= 4.0.2)
  rspec-rails (~> 2.14.1)
  sass-rails (~> 4.0.0)
  sdoc
  shoulda-matchers
  turbolinks
  uglifier (>= 1.3.0)

The Gemfile.lock file stores a complete snapshot of every version of every gem your Ruby on Rails application uses. The reason for this is simple. Let’s say you are using Rails 4.1.6 and Rails 5.0 comes out. You don’t want this new version to be pushed to your application during the next update. Why? You developed your application using the old version, and the new version may not be compatible with your code. That is why it is also important to check your Gemfile.lock into source control with the rest of your application.

The Gemfile.lock file not only stores exact version information, but bundler USES that version information to rebuild the snapshot on production. If you take a look at your Gemfile (not Gemfile.lock) for example you will see the following line:

1
gem 'coffee-rails', '~> 4.0.0'

Bundler knows that you used version 4.0.1 during development. When this file is pushed to production and you run a bundle install –deployment, bundler will recreate a snapshot of all of the gems that you were using on your development machine.

When does this file get updated? Any time you add a new gem to your gemfile (and run a bundle install) or type bundle update [gem name] your Gemfile.lock will get updated. If you attempt to update the version of a Gem in your Gemfile, bundler will warn you to do a bundle update the next time you try to run a bundle install.

1
2
3
4
5
You have requested:
  coffee-rails ~> 4.0.2

The bundle currently has coffee-rails locked at 4.0.1.
Try running 'bundle update coffee-rails'

In this case, you would be unable to proceed until you run bundle update coffee-rails, which would then update your Gemfile.lock to include the new version of coffee-rails. This is also why it’s disastrous to run a bundle update without specifying a gem. Bundle update rebuilds the entire Gemfile.lock file from scratch, blowing away all of the old versions and replacing them with the latest ones allowed by the Gemfile.

So far so good, the Gemfile.lock file is designed to save headache and frustration when deploying your application both across development machines as well as to production. It’s always a good idea to make sure that you check this file into source control and be aware of how it works. That’s it! See ya!

Ruby on Rails With Endless Scrolling

Ruby on Rails with Endless Scrolling

Endless scrolling allows a website to let users avoid having to click page links or pagination in order to load additional pages of content. It is used by a number of sites such as Pinterest in order to enhanced the user experience. This article will show you how to implement endless scrolling in your Rails application. Let’s run through this with me.

Create Rails Project
To create a Rails project; open up your terminal and type commands below:

1
rails new endless_scrolling -d mysql

Setting up
Ruby on Rails endless scrolling uses the will_paginate gem to manage paging. This has a couple of advantages.

First, if your endless scrolling code doesn’t work properly or is disabled, the pagination links themselves will still be present and allow the user to page.

Second, the will_paginate gem provides us with the pagination functionality itself so that we do not need to reinvent the wheel.

To get started, add the will_paginate gem to your Gemfile file.

Gemfile
1
gem 'will_paginate', '~> 3.0.7'

Then run a bundle install to install the gem:

1
bundle install

we will create a simple Post model with the fields title, and body. In addition, we will create a simple Posts controller with an index method. Run the commands below to create these items:

1
2
3
rails g model Post title body:text
rake db:migrate
rails g controller Posts index

Then open up your routes (config/routes.rb) file and modify it so that it looks like the code listed below:

routes.rb
1
2
3
Rails.application.routes.draw do
  root to: "posts#index"
end

Then we need some seed data to play with. Open up your seeds.rb file and add in the code listed below. This code will create 100 posts for us to play with:

seeds.rb
1
2
3
4
5
(1..100).each do |i|
  Post.create!(title: "Lipsum Post #{i}", body: %{
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. In feugiat purus dapibus fermentum sagittis. Fusce in tempus felis. Phasellus a erat ut lorem lacinia bibendum. Vivamus viverra facilisis neque, in scelerisque urna pharetra vel. Donec a est mauris. Integer eget metus quis eros egestas elementum. Integer bibendum risus hendrerit dapibus tempor. Fusce placerat in orci vitae tincidunt.
  })
end

Then run rake db:seed to create the seed data:

1
rake db:seed

Then open up your Posts controller (app/controllers/posts_controller.rb) and modify it so that it looks like the code listed below:

1
2
3
4
5
class PostsController < ApplicationController
  def index
    @posts = Post.paginate(:page => params[:page], :per_page => 20)
  end
end

Now modify the index view for your Posts controller so that it looks like the code listed below.

posts_controller.rb
1
2
3
4
5
class PostsController < ApplicationController
  def index
    @posts = Post.paginate(:page => params[:page], :per_page => 20)
  end
end

Then modify the index (app/views/posts/index.html.erb) view for your Posts controller so that it looks like the code listed below:

index.html.erb
1
2
3
4
5
<div id="posts">
  <h1>Posts</h1>
  <%= render @posts %>
</div>
<%= will_paginate @posts %>

Then let’s create the post partial. Create a file called _post.html.erb (app/views/posts/_post.html.erb) for your Posts controller and add in the code listed below:

_post.html.erb
1
2
3
4
<div class="post">
  <h2><%= post.title %></h2>
  <p><%= post.body %></p>
</div>

If you were to start a rails server at this point, you’d see a typical paginated list of posts. Now it’s time to add in the javascript that will make endless scrolling work. Open up your application.js (app/assets/javascripts/application.js) file and add in the code listed below:

application.js
1
2
3
4
5
6
7
8
9
10
11
12
$(document).ready(function() {
  if ($('.pagination').length) {
    $(window).scroll(function() {
      var url = $('.pagination .next_page').attr('href');
      if (url && $(window).scrollTop() > $(document).height() - $(window).height() - 50) {
        $('.pagination').text("Please Wait...");
        return $.getScript(url);
      }
    });
    return $(window).scroll();
  }
});

Then create a file called index.js.erb (app/views/posts/index.js.erb) for your Posts controller and add in the code listed below:

index.js.erb
1
2
$('#posts').append('<%= escape_javascript render(@posts) %>');
$('.pagination').replaceWith('<%= escape_javascript will_paginate(@posts) %>');

The code works by watching the window’s scroll event. When the user scrolls past the specified threshold, more posts are loaded using AJAX. That’s it, thank you!. See ya! :)

Ruby on Rails Generate Random Data

Ruby on Rails Generate Random Data

Sometimes we need to programmatically generate text in Ruby on Rails. We may not have any data available to play with or we may need text in order to mock up the user interface. In this article I will cover 2 different methods of generating random text. Let’s run through this with me.

Random Letters
If you just need fill text, you can add this helper to your application helper (app/helpers/application_helper.rb):

application_helper.rb
1
2
3
4
5
6
7
8
9
10
11
module ApplicationHelper
  def random_string(length, include_uppercase = true, include_lowercase = true, include_numbers = false)
    l = []
    l.push ('a'..'z') if include_uppercase
    l.push ('A'..'Z') if include_lowercase

    l.push (0..9) if include_numbers
    l = l.map { |i| i.to_a }.flatten
    string = (0...length).map { l[rand(l.length)] }.join
  end
end

The helper has 1 required argument is length, which determines the length of the string. To generate a random string of 200 characters, call the helper like below:

1
<%= random_string(200) %>

Forgery Gem
The forgery gem provides a great way to generate random data. Not only can forgery generate random words (based off lorem ipsum), but it can also generate random email addresses, and much more. To use forgery, just include the forgery gem in your gemfile:

Gemfile
1
gem 'forgery', '0.6.0'

Then run bundle install to install the Gem.

After installing the Gem, you are ready to go to generate words:

1
<%= Forgery(:lorem_ipsum).words(100) %>

To generate a random email address:

1
<%= Forgery('internet').email_address %>

So far so good, I hope all you guys enjoy it. See ya! :)

Ruby on Rails Uploads Multiple Files With DropzoneJS and Paperclip Gem

Ruby on Rails Uploads Multiple Files with DropzoneJS and Paperclip Gem

DropzoneJS is a javascript library for allowing multiple file uploads via AJAX. It features drag and drop support, folder support, and much more on browsers that support these features.

In this article I will show you how to implement multiple images files uploads directly to paperclip using DropzoneJS. Let’s run through this with me.

Create Rails Project
To create a Rails project; open up your terminal and type commands below:

1
rails new dropzone -d mysql

Add Gems
We will add two gems to our Gemfile. dropzonejs-rails gem is a helper gem that integrates DropzoneJS into our Rails app. paperclip for processing image uploads.

Open up your Gemfile and add in the lines listed below:

Gemfile
1
2
gem "paperclip", "~> 4.2"
gem 'dropzonejs-rails'

Now let’s run a bundle install to install the gems:

1
bundle install

Create a Image Model
Now we will create a model to store our image information for Paperclip. Run the command below to create the image model and migrate the database:

1
2
rails g model image avatar:attachment
rake db:migrate

Then add some code to Image model to tell paperclip we want to have an attachment attached. Open up your image model (app/models/image.rb:) and add the code listed below:

image.rb
1
2
3
4
class Image < ActiveRecord::Base
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
  validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end

Create a Images Controller
Then create an Images controller which will be used to display and allow the upload of our images. Run the command below to create this controller:

1
rails g controller images index create

Then update our routes file to set up the routes for our images controller. Open up the routes file (config/routes.rb) and modify it:

routes.rb
1
2
3
4
Rails.application.routes.draw do
  resources :images, only: [:index, :create]
  root to: "images#index"
end

Then modify our Images controller to add logic to handle the file upload as well as listing each of the images. Open up the Images controller (app/controllers/images_controller.rb) and modify it:

images_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ImagesController < ApplicationController
  def index
    @images = Image.all
    @image = Image.new
  end

  def create
    @image = Image.new(image_params)

    if @image.save
      render json: { message: "success", fileID: @image.id }, status: 200
    else
      render json: { error: @image.errors.full_messages.join(',')}, status: 400
    end
  end

  private
  def image_params
    params.require(:image).permit(:avatar)
  end
end

DropzoneJS expects a json return, so the create method returns a JSON success or failure based on whether the image was uploaded successfully or not.

Then add Bootstrap to our application. Open up your application layout (app/views/layouts/application.html.erb)and modify it:

application.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
  <title>DropzoneJS</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= stylesheet_link_tag    'http://yandex.st/bootstrap/3.1.1/css/bootstrap.min.css', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'http://yandex.st/bootstrap/3.1.1/js/bootstrap.min.js', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>
  <%= yield %>
</body>
</html>

Well, then create our views. First let’s create the index view (app/views/images/index.html.erb). Open up your index view for the images controller and modify it:

index.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
<h1>My Images</h1>

<%= form_for(Image.new, html: { multipart: true, class: "dropzone"}) do |f|  %>
  <div class="fallback">
    <%= f.file_field :avatar %><br>
    <%= f.submit "Upload my Avatar" %>
  </div>
<% end %>

<div class="index">
  <%= render "index" %>
</div>

Then we need to add some JavaScript to tell Rails how to handle the remote ajax file processing that we will do using dropzone. Create a view called app/views/images/index.js.erb for your images controller and add the code listed below:

index.js.erb
1
$(".index").html("<%= escape_javascript(render('index')) %>")

Then create the partial that we reference in the previous code. Create a new partial called app/views/images/_index.html.erb for your images controller and add the code listed below:

_index.html.erb
1
2
3
4
5
<% @images.each do |image| %>
  <div class="img-thumbnail">
    <%= image_tag image.avatar.url(:thumb), alt: image.avatar.url(:thumb) %>
  </div>
<% end %>

Then modify our application.css and add the dropzone css require. Open up your app/assets/stylesheets/application.css file and modify it:

application.css
1
2
3
4
5
/*
 *= require_tree .
 *= require dropzone/dropzone
 *= require_self
 */

Then modify our application.js and add the dropzone js require. Open up your app/assets/javascripts/application.js file and modify it:

application.js
1
/= require dropzone

Then add a bit more JavaScript to finish things up. Open up your app/assets/javascripts/images.js file and add in the code listed below:

images.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(document).ready(function(){
  // disable auto discover
  Dropzone.autoDiscover = false;

  var dropzone = new Dropzone (".dropzone", {
    maxFilesize: 256, // set the maximum file size to 256 MB
    paramName: "image[avatar]", // Rails expects the file upload to be something like model[field_name]
    addRemoveLinks: false // don't show remove links on dropzone itself.
  });

  dropzone.on("success", function(file) {
    this.removeFile(file);
    $.getScript("/images");
  })
});

So far so good, if you start your Rails server and navigate to http://localhost:3000 you will notice that you can drag and drop images onto the app. On certain browsers, such as Google Chrome, you can even drag and drop one or more folders of images onto the dropzone placeholder and have them upload. In addition you can also click the dropzone and select a file via the file selection screen. That’s it! See ya! :)

Use Git With Ruby on Rails Project

Install Git on Linux/Ubuntu

Well, in the previous article I’ve shown you ”Install Git on Linux/Ubuntu”, and in this article I want to show you “Create Ruby on Rails project and using Git”. Let’s run through this with me.

Create Ruby on Rails Project
Type command below to create a Rails project:

1
rails new todo -d mysql

Initialize Git
Type command below to initialize git:

1
2
cd todo
git init

Ignore File/Dir
Git uses file .gitignore to determine which files and directories to ignore, before you make a commit.

.gitignore file should be committed into your repository, in order to share the ignore rules with any other users that clone the repository.

Type command below to create a .gitignore file:

1
vim .gitignore

Then type file/dir or content that you want git to ignore:

.gitignore
1
2
3
4
5
6
log/*.log
tmp/**/*
config/database.yml
db/*.mysql
/public/assets/**
/vendor/bundle

Type command below to add Rails project into git:

1
git add .

Type command below to commit into git:

1
git commit -m "initialize income"

And type command below to push to the repository branch master:

1
git push origin master

Install Git on Linux/Ubuntu

Install Git on Linux/Ubuntu

Overview
Git is a free and open source distributed version control system with an emphasis on speed, data integrity, and support for distributed, non-linear workflows.

Installation
Use command line below to update local package index and then install the packages:

1
2
sudo apt-get update
sudo apt-get install build-essential libssl-dev libcurl4-gnutls-dev libexpat1-dev gettext unzip

Setting Up Git
Now you have git installed, you need to do a few things so that the commit messages that will be generated for you will contain your correct information.

You need to provide your name and email address by using git config because git embeds this information into each commit you do. You can go ahead and add this information by typing:

1
2
git config --global user.name "Your Name"
git config --global user.email "youremail@domain.com"

You can see all of the configuration items that you have been set by typing command below:

1
git config --list

What you will see:

1
2
user.name=Your Name
user.email=youremail@domain.com

The information is stored in the configuration file, which you can optionally edit by hand with your text editor like this:

1
vim ~/.gitconfig
1
2
3
[user]
  name = Your Name
  email = youremail@domain.com

So far so good, now you should have git installed and ready to use on your system. To learn more about how to use Git, check out these: www.try.github.io

Ruby on Rails Connect to Multiple Databases and Migrations

Ruby on Rails connect to Multiple Databases And Migrations

Ruby on Rails connect to Multiple Databases and using ActiveRecord with multiple databases, it’s really simple take it easy. Let’s run through this.

Rake Tasks
Well, I want to handle migrations for two databases, so I need two separate Rake tasks to handle that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
desc "Migrate the database through scripts in db/migrate directory."

namespace :db do
  task :migrate do
    Rake::Task["db:migrate_db1"].invoke
    Rake::Task["db:migrate_db2"].invoke
  end

  task :migrate_db1 do
    ActiveRecord::Base.establish_connection DB1_CONF
    ActiveRecord::Migrator.migrate("db/migrate/db1/")
  end

  task :migrate_db2 do
    ActiveRecord::Base.establish_connection DB2_CONF
    ActiveRecord::Migrator.migrate("db/migrate/db2/")
  end
end

My first task is db:migrate that delegates out to db:migrate_db1 & db:migrate_db2.

Each of those establish a connection to the database and then runs the migrations from their own separate folders. This allows you to store migrations in separate folders so you can easily manage them.

The migrations are exactly the same as normal.

Database Connections
In order to get those migrations to work, I need to configure the database connections. I’m going to define everything in the database.yml just like normal, but with a different naming convention:

database.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
defaults: &defaults
  username: root
  password: 1234567
  adapter: mysql2
  encoding: utf8
  collation: utf8_unicode_ci

db1:
  development:
    database: db1_development
    host: localhost
    <<: *defaults

  test:
    database: db1_test
    host: localhost
    <<: *defaults

  staging:
    database: db1_staging
    host: localhost
    <<: *defaults

  production:
    database: db1_production
    host: localhost
    <<: *defaults

db2:
  development:
    database: db2_development
    host: localhost
    <<: *defaults

  test:
    database: db2_test
    host: localhost
    <<: *defaults

  staging:
    database: db2_staging
    host: localhost
    <<: *defaults

  production:
    database: db2_production
    host: localhost
    <<: *defaults

I configure two separate databases db1 & db2.

Then I need to configure the app to load these now. I open application.rb or environment file(s):

application.rb
1
2
3
4
5
6
ENV['ENV'] ||= 'development'

db_conf = YAML::load(File.open(File.join(APP_PATH,'config','database.yml')))

DB1_CONF = db_conf["db1"][ENV['ENV']]
DB2_CONF = db_conf["db2"][ENV['ENV']]

Take a look at what’s going on:
- I set the database configuration to use. You can just use Rails.env here instead of ENV[‘ENV’].
- I load up the database.yml config and parse it with YAML.
- I grab the configuration from the file for each db and the correct environment that I’m running in.

Connecting Models
When I’m working with multiple databases, I like to explicitly setup the connections inside the models themselves instead of inheriting from ActiveRecord::Base and using subclasses.

user.rb
1
2
3
class User < ActiveRecord::Base
  establish_connection DB1_CONF
end
product.rb
1
2
3
class Product < ActiveRecord::Base
  establish_connection DB2_CONF
end

Well, All you really need to do is load the configurations, establish the database connections, and setup the migrations to load from a specific directory for each database.

So far so good, See ya! :)

ChicagoBoss Installation

ChicagoBoss Installation

Overview

In software development, using a framework is almost a rule for fast, clean, easy readable and standardized coding. Chicago Boss (http://www.chicagoboss.org)is a framework that is heavily inspired by Rails. Set up and use Chicago Boss is easy as falling off a log. Chicago Boss allows you to code with the aforementioned standards in Erlang. Plus, offers conveniences of modern web development, including WebSocket and Comet. Basic features of Chicago Boss listed below:
- 100% asynchronous I/O
- Support for Erlang and Elixir code
- BossDB: Database connection layer with an advanced ORM which with built-in support for Mnesia, MongoDB, MySQL, PostgreSQL, Riak and Tokyo Tyrant
- BossCache: Database caching layer
- BossMQ: Cluster–wide, channel–based message queue
- BossRouter: URL router
- BossSession: Session storage layer
- BossNews: Event listener, model event system
- BossMail: Built-in email server
- Django and Jade template support
- Very clean controllers as result of pattern matching
- Auto document generation for models
- An useful admin interface
- Automatic code reloading

ChicagoBoss Installation

Installation

This short guide will help you get Chicago Boss installed and working on your system. Chicago Boss generally isn’t installed to global system path. Typically, Chicago Boss will be copied to a development directory in your path.

Requirement
Chicago Boss is written in the Erlang programming language, so naturally you will need to install Erlang on your system. You may remember my previous article post about Install Erlang Using Repository on Ubuntu.

Download a Chicago Boss
Download the Chicago Boss source code from here: http://www.chicagoboss.org.

Open the Archive

1
tar xzf ChicagoBoss-*.*.*.tar.gz

Compile the Code

1
2
cd ChicagoBoss-*.*.*
make

Create a New Project

1
make app PROJECT=project_name

Enter the New Project Dir and Run the Development Server

1
2
cd ../project_name
./init-dev.sh

Enjoya
Point your browser to http://localhost:8001
If all is well you will see a forbidding error message about the requested template — not to worry, the new project is empty so there is nothing to serve.

So far so good, see you in the next articles. :)

Erlang Message Passing

Erlang Message Passing

The communication model (among processes) in Erlang is message passing. Erlang processes share no memory. The way that processes communicate is via (asynchronous) message passing. Every process (even the shell) holds a mailbox queue where incoming messages are placed until received by the process. Message passing is asynchronous because the sending process does not block on send. On the other hand, receiving a message in Erlang is a blocking operation.

Characteristics

In this subsection I will describe some of the characteristics of message passing in Erlang.

Asynchronous
Message passing in Erlang is a non-blocking operation.

Data Copy
The message’s data are copied from the sending process to the receiver’s message queue, so the receiver gets a fresh copy of the data.

Ordering
Erlang runtime guarantees that if two messages are sent from node A to node B and both are delivered, then the ordering of these messages is kept (because ordering).

Successful Send
The send operation always succeeds (even if the target is a non-existing process) and evaluates to the data sent. An exception is when trying to send data to a non-existing registered process.

Sending Messages

Erlang uses the exclamation mark (!) as the operator for sending a message.

Syntax:

1
2
%send message Message to the process with pid Pid
Pid ! Message

Send multiple messages “at once”:

1
2
3
Pid1 ! Message, Pid2 ! Message, Pid3 ! Message
Pid1 ! (Pid2 ! (Pid3 ! Message))
Pid1 ! Pid2 ! Pid3 ! Message

Example:

As I have mentioned before, the shell is nothing more than a process. As a process, it has a message queue. In order to print and empty the shell’s message queue we can use the flush/0 BIFs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
1> self() ! erlang_term_can_be_sent.
erlang_term_can_be_sent
2> flush().
Shell got erlang_term_can_be_sent
ok
3> self() ! [this, is, a, list, 'of', atoms].
[this,is,a,list,'of',atoms]
4> self() ! {this, [is, a], tuple, {'!', '!'}}.
{this,[is,a],tuple,{'!','!'}}
5> self() ! {self(), 123}.
{<0.35.0>,123}
6> flush().
Shell got [this,is,a,list,'of',atoms]
Shell got {this,[is,a],tuple,{'!','!'}}
Shell got {<0.35.0>,123}
ok
7> Pid1 = self(), Pid2 = self(), Pid3 = self().
<0.35.0>
8> Pid1 ! msg, Pid2 ! msg, Pid3 ! msg.
msg
9> flush().
Shell got msg
Shell got msg
Shell got msg
ok
10> Pid1 ! (Pid2 ! (Pid3 ! msg)).
msg
11> flush().
Shell got msg
Shell got msg
Shell got msg
ok
12> Pid1 ! Pid2 ! Pid3 ! msg.
msg
13> flush().
Shell got msg
Shell got msg
Shell got msg
ok

Receiving Messages

Erlang uses pattern matching for receiving messages (same as in function clause selection and the case statement). The receive statement is used to deliver messages from the message queue.

Syntax:

1
2
3
4
5
6
7
8
receive
  Pattern1 when Guard1 ->
    ToDo1;
  Pattern2 when Guard2 ->
    ToDo2;
  _Other ->
    Catch_all
end

Receiving Order
The message processing is done in a FIFS (First In – First Served) order. Every incoming message is placed in the tail of the process’ message queue. When a receive statement is meet the following processing happens:
1. The first message (head of the message queue) is pattern matched against the first receive clause. If match, execute the clause’s body, else go to the next step.
2. The same message is pattern matched against the second (if any) receive clause. If match, execute the clause’s body, else go to the next step.
3. … 4. The same message is pattern matched against the last clause. If match, execute the clause’s body, else go to the next step. 5. The same iterative process starts again from step 1, but now with the next message from the message queue.

The message (if any) that is delivered through receive is removed from the message queue.

Example:

pingpong.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
-module(pingpong).
-export([play/1]).

play(N) when is_integer(N), N > 0 ->
  Pong = spawn(fun pong/0),
  ping(N, Pong).

ping(0,Pong) ->
  Pong ! exit,
  ok;
ping(N, Pong) ->
  Pong ! {self(), ping},
  receive
    pong ->
      io:format("~w : pong [~w]~n", [self(), N])
  end,
  ping(N - 1, Pong).

pong() ->
  receive
    {From, ping} ->
      io:format("~w : ping~n", [self()]),
      From ! pong,
      pong();
    exit ->
      ok
  end.

Example running:

1
2
3
4
5
6
7
8
9
10
11
12
1> c(pingpong).
{ok,pingpong}
2> pingpong:play(4).
<0.49.0> : ping
<0.39.0> : pong [4]
<0.49.0> : ping
<0.39.0> : pong [3]
<0.49.0> : ping
<0.39.0> : pong [2]
<0.49.0> : ping
<0.39.0> : pong [1]
ok

Timeout
Receive is a blocking statement; it blocks until a message that matches one of the clauses is placed in the incoming message queue. Erlang allows the programmer to explicitly unblock the receive statement using a timeout (if a matching message is not delivered until the timeout expires). The complete format of receive statement, including the after construct.

Syntax:

1
2
3
4
5
6
7
8
9
10
receive
  Pattern1 when Guard1 ->
    ToDo1;
  Pattern2 when Guard2 ->
    ToDo2;
  _Other ->
    Catch_all
after Millisecs ->
  ToDo_timeout;
end

Example:

timeout.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-module(timeout).
-export([start/0, sleep/1]).

start() ->
  spawn(fun timeout/0).

timeout() ->
  receive
    cancel ->
      io:format("Timeout canceled~n")
  after 2000 -> % 2 seconds
    io:format("Timeout triggered~n"),
    timeout()
  end.

%a sleep function
sleep(Ms) ->
  io:format("Sleeping for ~w ms~n", [Ms]),
  receive
  after Ms ->
    done
  end

Example running:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1> c(timeout).
{ok,timeout}
2> P = timeout:start().
<0.42.0>
Timeout triggered
Timeout triggered
3> P ! cancel.
Timeout canceled
cancel
4> timeout:sleep(1000).
Sleeping for 1000 ms
done
5> timeout:sleep(3000).
Sleeping for 3000 ms
done