Slim on Rails

Slim on Rails

The first thing you need to do is add a couple gems to the Gemfile. The slim gem tells Rails how to parse the Slim syntax. The slim-rails gem overrides the Rails generators for ERB and replaces them with Slim generators. Add these gems to your Gemfile as below:

Gemfile
1
2
gem 'slim', '~> 2.0.3'
gem 'slim-rails', '~> 2.1.5'

Then run bundle install to install the gems:

1
bundle install

Then generate a Homes controller with a show action by running the command below:

1
rails g controller Homes show

Notice that the generated view ends in .slim, Rails has generated a slim file for us, courtesy of the slim-rails gem. Now let’s modify our routes file to set up a resource and add a root path. Open up your routes file (config/routes.rb) and modify it so that it looks somethings like:

routes.rb
1
2
root to: "homes#show"
resource :home, only: [:show]

Now you are ready to play with Slim. Open up the show view for homes (app/views/homes/show.html.slim) and modify it so that it looks somethings like:

show.html.slim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
javascript:
  alert("HELLO!!!!!")
h1 Welcome to my site
<b>inline html is supported</b>
p
  | The time is #{ Time.now }, 
    I Like to program in Ruby on Rails.
#hashtag I threw a hashtag in here!
#classy I'm classy!

p = Random.rand(10)

- if Random.rand(6) == 1
  |Lucky number 1!  You win!
br
br
small Goodbye!

Which translates to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script type="text/javascript">
  alert("HELLO!!!!!")
</script>

<h1>Welcome to my site</h1>
<b>inline html is supported</b>
<p>The time is 2015-02-22 00:24:59 - 0400, I Like to program in Ruby on Rails.</p>

<div id="hashtag">
  I threw a hashtag in here!
</div>

<div id="classy">
  I'm classy!
</div>

<p>2</p>
<br>
<br>
<small>Goodbye!</small>

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

Slim Template Language

Slim Template Language

Slim is a replacement for ERB, similar to HAML. Slim provides a nice lean syntax that’s easy to pick up and learn. In this article we will learn how to use Slim. Let’s run through this with me.

Basic Syntax
Slim is actually really easy to learn. Indentation matters, but the indentation depth can be chosen as you like. If you want to first indent 2 spaces, then 5 spaces, it’s your choice.

Example:

1
2
p
  | This is a very long paragraph

Which translates to:

1
2
3
<p>
  This is a very long paragraph.
</p>

In the above example you’ll notice two things. First, the pipe (|) character is used to delimit free-form text on a new line. Second, we simply used p to specify the paragraph tag. This works for any tag, for instance you could just as easily have done:

1
2
h1
  | Large Title

Or more simply:

1
h1 Large Title

In the above example that we didn’t specify the pipe (|) character. The pipe (|) character is only needed if we are entering free-form text on a new line.

You can create a div with a default class by using:

1
class

Which translates to:

1
<div class="class"></div>

You can create a div with an id by using:

1
#id

Which translates to:

1
<div id="id"></div>

What about html attributes? Well, we specify them similarly to how we would in html:

1
meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"

Which translates to:

1
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"></meta>

To specify a doctype:

1
doctype html

Which translates to:

1
<!DOCTYPE html>

Well, all is great, but what about Ruby code? Inserting Ruby code is pretty easy. Code that doesn’t return a result, such as if statements or loops, are prefixed with a dash (-).

1
2
- if @products.nil?
  p No results found. Please try again.

Which is equivalent to:

1
2
3
4
5
if @products.nil?
  <p>
    No results found.  Please try again.
  </p>
end

Slim will auto close your Ruby code as well, so end isn’t needed.

If you have code that returns output, such as the printing of a variable or property, you can use the equal (=) sign.

1
= current_user.name

Which is equivalent to:

1
<%= current_user.name %>

Your strings are Rubyized:

1
| Hello #{user.name}

You can embed javascript as well:

1
2
javascript:
  alert("hello world!")

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

Customize the Ruby on Rails Application Generator

Customize the Ruby on Rails Application Generator

So far if you create a Rails app, you know that it can quickly to do things like:
- Add RSpec and Cucumber.
- Disable/turn off Test Unit.
- Switch the default database engine to PostgreSQL.
- Add other Gems such as HAML, CoffeeScript, …

Luckily we can customize what the Rails app generator generates. In this article, I will use Rails app templates to customize the default behavior of the Rails application generator. Let’s run through this with me.

Rails App Templates
Rails app templates allow you to run actual commands during the generation process. For example, I want to install rspec and haml, create a readme.md file, and commit the whole thing to git. I can easily do this by creating an Rails application template. Let create a file called app_template.rb and add the codes below:

app_template.rb
1
2
3
4
5
6
7
8
9
10
remove_file 'README.doc'
create_file 'README.md'

gem 'rspec-rails'
gem 'haml-rails'
run 'bundle install'
generate 'rspec:install'

git :init
git add: '--all', commit: '-m "Initialize Commit"'

If you generate a new app with the parameters -m app_template.rb it will run the instructions you listed in the template. The code listed above will get executed when you run the following command:

1
rails new blog -m app_template.rb

If you browse your Rails project you’ll see that rspec, haml got installed and the default readme file was removed and a readme.md file was added, and finally everything was committed to git.

In addition, you can have the application template prompt the user for more information. The code listed below allows you to do like this:

app_template.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
remove_file 'README.doc'
create_file 'README.md'

gem 'rspec-rails'
gem 'haml-rails'
run 'bundle install'
generate 'rspec:install'

if yes? 'Do you wish to generate a root controller? (y/n)'
  name = ask('What do you want to call it?').underscore
  generate :controller, "#{name} show"
  route "root to: '#{name}\#show'"
  route "resource :#{name}, only: [:show]"
end

git :init
git add: '--all', commit: '-m "Initial Commit"'

In the code above, the yes? function will prompt the user with a yes/no question. The ask function will prompt the user for text input. In this case, we ask the user if they wish to generate a root controller, and if they say yes, we prompt them for a name.

So far so good, That’s it! See ya!

Liquid on Rails

Liquid on Rails

Now you have a basic grasp on the Liquid template engine itself, let’s learn how to utilize it in our Ruby on Rails application. First you need to add the gem to the Gemfile. Add the following line to the Gemfile:

1
gem 'liquid', '~> 2.6.1'

Then run bundle install to install the Liquid gem:

1
bundle install

Then create a model called Page. The Page model will be used to represent a page owned by a specific user. Run the commands below to create this model:

1
2
rails g model Page user:string template:text
rake db:migrate

Then open up your seeds (db/seeds.rb) file and modify it so that it looks somethings like below:

seeds
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
Page.delete_all

Page.create(id: 1, user: "JingLong", template: %{
  Hello {{ user }}, here is your shopping list.
  <ul>
    {% for item in list %}
      <li>{{ item.name }}</li>
    {% endfor %}
  </ul>
}

)

Page.create(id: 2, user: "Bunlong", template: %{
  What is up my man? Here is your shopping list.
  <ul>
    {% for item in list %}
      <li>{{ item.name }}</li>
    {% endfor %}
  </ul>
}
)

Page.create(id: 3, user: "Rubyist", template: %{
  HTTP 200:  Shopping List Found

  Items in your list:
  <ul>
    {% for item in list %}
      <li>{{ item.name }}</li>
    {% endfor %}
  </ul>
}

)

Then run rake db:seed command to seed the database with your sample data:

1
rake db:seed

Then create a homes controller that will allow you to play with liquid. Run the command below to create the homes controller:

1
rails g controller Homes show

Then create a pages controller. This controller will be used to display a user’s page. Run the commands below to create the pages controller:

1
rails g controller Pages show

Then modify your routes (config/routes.rb) file so that it looks somethings like below:

routes.rb
1
2
3
root to: "homes#show"
resource :home, only: [:show]
resources :pages, only: [:show]

Then modify your homes controller (app/controllers/homes_controller.rb) to pull down a list of all the user’s pages. Open up your homes controller and modify it so that it looks somethings like below:

homes_controller.rb
1
2
3
4
5
class HomesController < ApplicationController
  def show
    @pages = Page.all
  end
end

Then modify your pages controller (app/controllers/pages_controller.rb) to pull down the correct page for the specified user. Open up your pages controller and modify it so that it looks somethings like below:

pages_controller.rb
1
2
3
4
5
class PagesController < ApplicationController
  def show
    @page = Page.find(params[:id])
  end
end

Then create a few helper (app/helpers/pages_helper.rb) methods for use with this example. Open up your pages helper and modify it so that it looks somethings like below:

pages_helper.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
module PagesHelper
  def shopping_list(user)
    {"user" => user, "list" => shopping_list_items}
  end

  def shopping_list_items
    [
      { "name" => 'Apple', "quantity_needed" => "2"},
      { "name" => 'Stoberry', "quantity_needed" => "1"},
      { "name" => 'Cherry', "quantity_needed" => "3"},
    ]
  end
end

The codes above gives you some sample data to play around with.

Then modify your pages show view (pp/views/pages/show.html.erb) to look somethings like below:

show.html.erb
1
2
3
4
5
<h1><%= @page.user %>'s Personal Page</h1>

<% template = Liquid::Template.parse(@page.template) %>

<%= template.render(shopping_list(@page.user)).html_safe %>

The codes above tells Rails to render your template using the Liquid Template Engine.

Finally, open up the show view for your home controller (app/views/homes/show.html.erb) and add in the code listed below:

show.html.erb
1
2
3
4
5
6
<h1>User Pages</h1>
<ul>
  <% @pages.each do |page| %>
    <li><%= link_to "#{page.user}'s page", page_path(page) %></li>
  <% end %>
</ul>

If you fire up a rails server and visit your development site, you’ll notice that you can browse each user’s pages and get a customized version of each one.

However, what if you want to use the Liquid templating engine as a replacement for erb itself? take it easy, first, create a new file in the lib folder called liquid_view.rb (lib/liquid_view.rb) and add in the codes listed below:

liquid_view.erb
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
class LiquidView
  def self.call(template)
    "LiquidView.new(self).render(#{template.source.inspect}, local_assigns)"
  end

  def initialize(view)
    @view = view
  end

  def render(template, local_assigns = {})
    @view.controller.headers["Content-Type"] ||= 'text/html; charset=utf-8'

    assigns = @view.assigns

    if @view.content_for?(:layout)
      assigns["content_for_layout"] = @view.content_for(:layout)
    end
    assigns.merge!(local_assigns.stringify_keys)

    controller = @view.controller
    filters = if controller.respond_to?(:liquid_filters, true)
                controller.send(:liquid_filters)
              elsif controller.respond_to?(:master_helper_module)
                [controller.master_helper_module]
              else
                [controller._helpers]
              end

    liquid = Liquid::Template.parse(template)
    liquid.render(assigns, :filters => filters, :registers => {:action_view => @view, :controller => @view.controller})
  end

  def compilable?
    false
  end
end

Create an initializer called liquid_template_handler (config/initializers/liquid_template_handler.rb) and add the code listed below:

liquid_template_handler.erb
1
2
require 'liquid_view'
ActionView::Template.register_template_handler :liquid, LiquidView

Let restarting your Rails server you will be able to create actual views with the .liquid extension that uses the liquid templating engine.

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

Liquid Template Engine

Liquid Template Engine

Liquid is a templating engine that allows you to enable your users to quickly and easily customize your views at run-time while maintaining the safety, security, and integrity of your servers.

Liquid Syntax
In liquid, there are two different types of markup.

The first type of markup is output markup, is denoted by double sets of curly braces.

1
Hi {{ user.name }}

The second type of markup is tag markup, is typically used for logic and control structures such as loops.

1
2
3
4
5
<ul>
  {% for user in users %}
    <li>{{ user.name }}</li>
  {% endfor %}
</ul>

You can do basic if statements as well:

1
2
3
4
5
6
7
{% if user.name != 'JingLong' %}
  Hi JingLong!
{% elsif user.name == 'Bunlong' %}
  Hey Bunlong!
{% else %}
  Hello {{ user.name }}
{% endif %}

List of All of the Tags Available in Liquid

Tag Description
assign Assigns some value to a variable.
capture Block tag that captures text into a variable.
case Block tag, its the standard case…when block.
comment Block tag, comments out the text in the block.
cycle Cycle is usually used within a loop to alternate between values, like colors or DOM classes.
for For loop.
if Standard if/else block.
include Includes another template; useful for partials.
raw Temporarily disable tag processing to avoid syntax conflicts.
unless Mirror of if statement.


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

What Is Difference Between Path and URL in Ruby on Rails?

What is Difference Between Path and URL in Ruby on Rails?

Have you ever wondered what is difference between _path and _url in Ruby on Rails?

For example root_path and root_url. As it turns out, _path only returns the url relative to your domain.

For instance, root_path returns / while root_url returns http://mydomain.com/.

You should always use _url for redirects and _path for hyperlinks unless you have a good reason not to do so.

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

Stashing Codes Changes in Git

Stashing Codes Changes in Git

Using version control, is best to commit your code in small, discrete chunks rather than making large commits. However, What happens when you are working on a large change, and your boss comes to you and tells you they need an urgent bug fixed? With the git stash command you can quickly and easily store your code away and recall it for later use. Let’s run through this with me.

Stash the Code

1
git stash

Reapply the Changes You Sent to the Stash Type
What if you want to reapply your changes? Use git stash apply to reapply all the changes you stashed away with git stash.

1
git stash apply

List All of the Stashes You’ve Made Type
Git stash supports stashing multiple times. To see a list of all the code you’ve stashed, use git stash list. The git stash list will show you a list of all the stashes you’ve made.

1
git stash list

Stash Apply From the Earlier List
If the first stash is named stash@{1}, you can type git stash apply stash@{1} to apply the changes from that stash.

1
git stash apply stash@{1}

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

Secrets.yml File in Ruby on Rails

Secrets.yml File in Ruby on Rails

You maybe have noticed a file called secrets.yml in the config directory of a Ruby on Rails 4.1 project. This feature was added as part of Rails 4.1 in order to have a common storage location for the keys and credentials for various services. You can use the secrets.yml for everything from AWS credentials to your secret_key_base (the default in Rails 4.1).

secrets.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
development:
  secret_key_base: super_long_secret_key_for_development
  active_merchant_login: 112233
  active_merchant_password: super_secret_password

test:
  secret_key_base: super_long_secret_key_for_test
  active_merchant_login: 112233
  active_merchant_password: super_secret_password

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  active_merchant_login: <%= ENV["AM_LOGIN"] %>
  active_merchant_password: <%= ENV["AM_PASSWORD"] %>

You have add this file to your .gitignore file to avoid accidently pushing your keys to git. You can also store your production keys in this file if you wish.

To access the various keys in the secrets.yml file:

1
Rails.application.secrets.key_name

Example: The following code will returns the merchant login.

1
Rails.application.secrets.active_merchant_login # returns 112233 on development/test

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

Ruby on Rails Model Change Tracking With ActiveModel::Dirty

Ruby on Rails Model Change Tracking with ActiveModel::Dirty

ActiveModel::Dirty is a library that is built into Ruby on Rails that allows you to quickly and easily track what attributes on a model have changed. This article will show you how to use it.

Checking Whenever the Model Has Changed
Checking whether the model has changed using the changed? method:

1
product.changed?  # => false

If you change an attribute on the model, the changed? method will returns true:

1
2
product.name = "Mac Pro"
product.changed? # => true

Tracking the Change
You can track what the change by using the attr_change method:

1
product.name_change # => ["Mac Pro", "IBM ThinkPad"]

You can get a list of all of the changed attributes on the model as well:

1
product.changed # => ["name"]

You can get the original value using the attr_was method as well:

1
product.name_was #=> "IBM ThinkPad"

You can view a list of all of the original values using the changed_attributes method as well:

1
product.changed_attributes # => {"name" => "IBM ThinkPad"}

You can list all of the changes on the model using the changes method as well:

1
product.changes # => {"name" => ["IBM ThinkPad", "Mac Pro"]}

You can view changes that were made even after the model was saved using the previous_changes method as well:

1
2
3
4
5
<pre class="prettyprint">
  product.save
  product.changes # => {}
  product.previous_changes # => {"name" => ["IBM ThinkPad", "Mac Pro"]}
</pre>

You can view changes that were made even after the model was saved using the previous_changes method as well:

1
2
3
4
5
<pre class="prettyprint">
  product.save
  product.changes # => {}
  product.previous_changes # => {"name" => ["IBM ThinkPad", "Mac Pro"]}
</pre>

You can reset the model using the reload! method as well:

1
2
product.reload!
product.previous_changes # => {}

So far so good, for more detail Ruby on Rails API. That’s it! See ya!

Ruby Download File via FTP

Ruby Download File via FTP

Download files from FTP server is quite easy using Ruby.

Example:

1
2
3
4
5
6
7
8
require 'net/ftp'

ftp = Net::FTP.new
ftp.connect("your_host_name.com", 21)
ftp.login("your_username","your_password")
ftp.chdir("/your_directory")
ftp.passive = true
ftp.getbinaryfile("your_source_file", "your_dest_file")

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