What New With Foreign Keys in Rails 4.2?

What New with Foreign Keys in Rails 4.2?

Previous versions of Rails did not have the ability to create foreign keys without resorting to executing SQL statements directly. This lead to messy, database dependent solutions that weren’t very nice.

Luckily, Rails 4.2 rectifies this with new features to add and remove foreign keys. In this article we will discuss what foreign keys are, and how to add them to your database.

If you don’t know what a foreign key is, well, quite simply, a foreign key links one table to another’s primary key. For example, if I have an authors table and a books table, I could create a foreign key that points from books back to authors, linking the two tables together. Then, these two tables become linked. It means that I cannot add or update the record with invalid data for the author_id field in the books table. I can also tell the database server what to do when I update or delete the record. For example, I can tell rails to automatically delete child records when the parent is deleted (delete an author from the authors table and all the author’s books are deleted). I could also tell Rails to set the author_id column to null or to simply not let me delete the author while child records exist.

Add Foreign Keys
To add a foreign key to the books table:

1
add_foreign_key :books, :authors

We can also give the foreign key a custom name:

1
add_foreign_key :books, :authors, name: :my_foreign_key

If we are using a non Rails friendly database, we can specify the column names we wish to use for the foreign key. For example, let’s say the primary key of the authors table is author_id and the key in the books table is auid. We could simply use the following code to create the foreign key:

1
add_foreign_key :books, :authors, column: :auid, primary_key: :author_id

We can control the behavior of the foreign key as well. A list of the available behaviors are below. Independent behaviors can be set for both update as well as delete.
- :restrict (default) - Prevents changes from being made.
- :nullify - Sets the child columns to null.
- :cascade - Cascades down to the child records. For instance, deleting an author deletes the author’s books.

To specify behaviors, you simply use the on_delete or on_update parameters. For example, the following code would cascade deletes so that the books get deleted when the parent gets deleted.

1
add_foreign_key :books, :authors, on_delete: cascade

Delete Foreign Keys
It is just as easy to delete foreign keys:

1
remove_foreign_key :books, :authors

You can optionally specify the name of the foreign key to delete:

1
remove_foreign_key :books, name: :my_foreign_key

If you have non Rails friendly column names, you can specify the column name that contains the foreign key you wish to remove:

1
remove_foreign_key :books, column: :auid

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

Ruby on Rails _filter vs _action

Ruby on Rails _filter vs _action

If you are coming to Rails 4 from earlier versions of Rails, you may have noticed the new _action methods floating around.

Seeing these for the first time may have left you scratching your head a bit and asking “Aren’t these the same as the _filter functions in previous versions of Rails?” The answer is a resounding YES. For Rails 4.x, the rails team decided to rename the functions to better describe what they are doing. Don’t worry, the old functions still work. However it is recommended that you use the new syntax going forward, as the _filter functions may be deprecated in the future.

Below shows a list of the old and new functions:

Old Function New Function
before_filter Abefore_action
after_filter after_action
around_filter around_action
append_after_filter append_after_action
append_around_filter append_around_actionor DOM classes.
prepend_around_filter prepend_around_action
append_before_filter append_before_action
skip_before_filter skip_before_action
skip_around_filter skip_around_action
skip_after_filter skip_after_action
skip_filter skip_action_callback

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

Quickly Add Bootstrap to Your Project

Quickly Add Bootstrap to Your Project

Bootstrap is an amazing layout library that is awesome for building both prototypes as well as full blown websites. This very website makes extensive use of Bootstrap 3 to make things look awesome on both mobiles sites as well as the desktop.

What if we want to quickly prototype out a site using bootstrap? Fortunately you can easily add bootstrap to your site without downloading anything, simply reference the associated files on the Yandex CDN.

Yandex is a worldwide search engine that is extremely popular in russia. Their CDN is extremely fast and has many different libraries available. To add bootstrap via yandex, simply include them like so (this also include jQuery, since Bootstrap JS requires it).

1
2
3
<script src="http://yandex.st/jquery/1.11.1/jquery.min.js"></script>
<link href="http://yandex.st/bootstrap/3.1.1/css/bootstrap.min.css" media="screen" rel="stylesheet" />
<script src="http://yandex.st/bootstrap/3.1.1/js/bootstrap.min.js"></script>

A full list of the libraries available can be found on the yandex website. Note that it’s in russian, so you might need to translate it.

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

Respond With JSON in Ruby on Rails Application

Translate Your Ruby on Rails Application

When building a RESTful API in Rails application, there are many different options and gems you can use to format your JSON responses. This isn’t a post about how to build an API, but rather about some of the different popular options on how to define and structure JSON.

RABL
RABL is a DSL for generating both JSON and XML. In my mind it has a similar feel to Jbuilder, which I’ll discuss below. It’s works by creating a view with the extension .rabl, and defining which attributes, nodes, and relations you wish to include in the JSON response.

Here’s an example:

app/views/posts/index.rabl
1
2
3
4
collection @posts
attributes :id, :title, :subject
child(:user) { attributes :full_name }
node(:read) { |post| post.read_by?(@user) }

Active Model Serializer
Active Model Serializer is a great way to build JSON responses using an object oriented approach. The objects have a very similar feel to how your ActiveModel object is set up in terms of attributes and relationships. It also allows you to choose your adapter-to decide what type of JSON structure is produced-or to build your own. Popular supported formats are JSON-API and JSON-HAL.

1
2
3
4
5
class PostSerializer < ActiveModel::Serializer
  attributes :title, :body
  has_many :comments
  url :post
end

Jbuilder
jbuilder provides a very similar DSL to RABL. Jbuilder is included with Rails, so it is used quite a bit. Rails Casts has a free episode which goes into greater detail about Jbuilder. It’s very easy to use and provides a lot of flexibility in defining exactly what attributes are included in and how the response is formatted and nested.

app/views/message/show.json.jbuilder
1
2
3
4
5
6
7
8
json.content format_content(@message.content)
json.(@message, :created_at, :updated_at)

json.author do
  json.name @message.creator.name.familiar
  json.email_address @message.creator.email_address_with_name
  json.url url_for(@message.creator, format: :json)
end

Grape Entity
Grape Entity was extracted from Grape, which is a popular gem used for building RESTful APIs. Similarly to RABL and Jbuilder, it provides a DSL for defining entities which are the structure of your JSON response.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module API
  module Entities
    class Status < Grape::Entity
      expose :user_name
      expose :text, documentation: { type: "String", desc: "Status update text." }
      expose :ip, if: { type: :full }
      expose :user_type, :user_id, if: lambda { |status, options| status.user.public? }
      expose :contact_info do
        expose :phone
        expose :address, using: API::Address
      end
    end
  end
end

ROAR
ROAR allows you to build presenter classes to represent your data. It comes with support for JSON, JSON-HAL, JSON-API, and XML.

1
2
3
4
5
6
require 'roar/json'

module SongRepresenter
  include Roar::JSON
  property :title
end

ActiveModel or Hash
This may seem like a strange thing to point out, but for very simple cases, you can simply call the to_json method on either an ActiveModel object or a native Ruby Hash.

1
2
3
4
5
6
# Using an @organization model
respond_to do |format|
  format.json do
    render json: @organization.to_json
  end
end
1
2
3
4
5
6
7
8
9
# Using a plain Ruby Hash
respond_to do |format|
  format.json do
    render json: {
      name: @user.name,
      email: @user.email
    }.to_json
  end
end

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

Create QR Codes in Ruby on Rails Application

Create QR Codes in Ruby on Rails Application

Barby is a great gem for generating a barcode or QR code. You can choose to output it as any number of barcode types or as a QR code. This example will use a QR code but I have successfully used the Code128 barcode which is fairly common in the retail space.

Add Barby to your gem file:

Gemfile
1
2
gem 'barby',  '~> 0.6.2'
gem 'rqrcode','~> 0.4.2'

Here is an example helper for generating the QR code as base64 encoded png data:

1
2
3
4
5
6
7
8
9
10
def generate_qr(text)
  require 'barby'
  require 'barby/barcode'
  require 'barby/barcode/qr_code'
  require 'barby/outputter/png_outputter'

  barcode = Barby::QrCode.new(text, level: :q, size: 5)
  base64_output = Base64.encode64(barcode.to_png({ xdim: 5 }))
  "data:image/png;base64,#{base64_output}"
end

And an example call from your view:

1
%img{src: generate_qr("http://geekhmer.github.io/"), class: "qr-code"}

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

Translate Your Ruby on Rails Application

Translate Your Ruby on Rails Application

If you’re planning to take over the world, you’ll need to convince everyone to speak your language, or better yet, why don’t you offer them a website that speaks their language. The goal is to have a website available in multiple languages, and for the visitors to be able to toggle over to the language they are most comfortable with.

Routing
I like to nest all of my routes inside of a :locale scope. I also limit the locale options to a set that I have predefined in an initializer. You could also choose to deal with locale validity later on in the flow (before_action method), but it is up to you.

config/routes.rb
1
2
3
4
5
scope "(:locale)", locale: /#{MySite::ROUTE_LOCALES.keys.join("|")}/ do
  root :to => 'home#index'
  resources :pages
  # etc...
end
onfig/initializers/my_site.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
module MySite
end

MySite::LOCALES = {
  en:    "English",
  kh:    "Khmer",
  fr:    "French",
  en_us: "US English",
  en_uk: "UK English",
}

MySite::ROUTE_LOCALES = MySite::LOCALES.keys.each_with_object({}) do |locale, hsh|
  hsh[locale.to_s.tr("_","-")] = locale if locale.to_s.length > 2
end

This line of code will make sure all of your routes have the current locale in them.

app/controllers/application_controller.rb
1
2
3
def default_url_options(options={})
  { locale: I18n.locale }.merge(options)
end

Determining Locale
I usually have a before_action filter which does its best to determine the URL of the application. You might have other things in here too if you keep track of the preferred locale in a cookie, or if it is attached to the user’s session data or account. You may also want to use the HTTP_ACCEPT_LANGUAGE to determine if there is a match.

app/controllers/application_controller.rb
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
class ApplicationController < ActionController::Base
  before_action :determine_locale

  protected

  def determine_locale
    locale = if params.include?(:new_locale) && MySite::ROUTE_LOCALES.keys.include?(params[:new_locale])
      params[:new_locale]
    elsif params.include?(:locale)
      params[:locale]
    else
      locale_from_url(request.host) || I18n.default_locale
    end

    set_locale(locale)
  end

  def locale_from_url(host)
    # ... determine locale from host if you have different domains
    # for different locales
  end

  def set_locale(locale)
    I18n.locale = locale.to_s.gsub("-","_").to_sym
  end
end

Static Text
The developers should be entering their keys into the yml files located in the locales folder if your rails application. I normally only have one for English, and then use other I18n backends (Redis for example) serve up the other translations. If the translations are in Redis, you will obviously need code that puts them there. I am working on an engine for this called Idioma which persists the translations using ActiveRecord and also to Redis at the same time.

Dynamic Content
Because I18n comes built in to Rails, you won’t need to install many gems. But for dynamic content I recommend Globalize. Along with this one is a handy gem called Globalize Accessors which will help you when creating forms to enter this data in.

1
2
3
4
class Page < ActiveRecord::Base
  translates :title, :body, fallbacks_for_empty_translations: true
  globalize_accessors locales: MySite::LOCALES.keys, attributes: [:title, :body]
end

Dynamic Content
One thing I set up are fallbacks… this is so you can translate English once, and only when there is a locale that differs from the default do you need to specifically translate it for that locale. Example, in the US colour is spelled like color.

config/application.rb
1
2
3
4
5
6
7
config.i18n.default_locale = :en_ca
config.i18n.fallbacks = {
  en_us: :en,
  kh   : :kh,
  en_uk: :en,
  fr_lu: :fr,
}

Having Your Website Translated
Because the translation team probably isn’t the same as the dev team, and they probably don’t have access to your code repository nor know how to edit yml files, you will want to have another way of giving them access to the translations. There is an established tool called Tolk.

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

Ruby on Rails Model Generator Useful Shortcuts

Ruby on Rails Renaming a Database Column

rails generate command provides a lot of useful functionality, however some of it may not be immediately known to you as a developer. In this article we will explore a number of useful shortcuts available in the rails model generator.

Basics

Let’s start with the basic command line usage.

1
rails g model User

rails g is the same thing as rails generate. Both commands do the same thing. We will use this shortcut throughout this article.

1
rails g model Product name quantity:integer

This command generates a model named product with 2 fields, name, which is a string, and quantity, which is an integer. By not specifying the type for name, rails defaults to using string. Below is a complete list of types that you can use with the modal generator.

Field Type Lists
- integer
- primary_key
- decimal
- float
- boolean
- binary
- string
- text
- date
- time
- datetime
- timestamp

You can also specify the size of a field as seen below.

1
rails g model Client name:string{ 100 }

This will create a name field with a limit of 100 characters. For the decimal type, you can specify a precision and scale value as well.

1
rails g model Product name price:decimal{ 12, 2 }

Namespaced Models
You can create namespaced models as well. This is useful for example, in creating a special set of administrative users that are separate from your regular users. Running the command below will place the user model in the Admin namespace, which will have a prefixed table name of admin_ in the database.

1
rails g model admin/user

As you can see from the code listed below, the user belongs to the admin namespace like mentioned earlier.

app/models/admin/user.rb
1
2
class Admin::User < ActiveRecord::Base
end

Adding an Index
You can also add a database index right from the command line.

1
rails g model Site name:string:index

In addition, you can make the index unique.

1
rails g model Client name:string:uniq

Model Relationships

You can specify a basic relationship between models.

1
rails g model User client:references

This will create a user with a column named client_id, add an index, and automatically add a belongs_to relationship to the User model.

You can also make the relationship polymorphic.

1
rails g model picture imageable:references{ polymorphic }

This will set up a polymorphic relationship for pictures. Polymorphic relationships allow you to ‘share’ a table between many different models. For instance, Products and People can both have pictures.

The rails model generator exposes a lot of useful functionality that can save time if used properly. Thanks for reading!

Ruby on Rails Renaming a Database Column

Ruby on Rails Renaming a Database Column

To rename a database column, first you need to create a migration:

Terminal commands line:

1
rails g migration RenameColumnXinTableYtoZ

Next you need to edit the migration and add the following line:

1
rename_column :table, :old_column, :new_column

Finally, please run a rake db:migrate and you are all set.

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

How to Uninstall RVM?

How to uninstall RVM?

There are times when you may need to completely remove RVM. For example, lets say that your installation is corrupt, or you don’t wish to use RVM anymore. Luckily this is easy to do. The first thing we need to do is to tell RVM to remove itself. This can be accomplished with the rvm impode command. Simply type:

1
rvm implode

Once you do that, RVM should remove itself. The next thing you need to do is uninstall the ‘rvm’ gem. Simply type:

1
gem uninstall rvm

This will uninstall the RVM gem.

The next thing you need to do is check to make sure that RVM is removed from your path. You need to check files like .bashrc, .bash_profile, and .profile to make sure all traces of the path are removed.

The final thing you need to do is make sure both the .rvm and .rvmrc files have been removed. simply type:

1
ls -a ~

This will list all of the files in your home directory. Type the following lines to remove the .rvm and .rvmrc files if they exist:

1
2
rm -rf .rvm
rm -rf .rvmrc

So far so good, if you no longer have a Ruby installation on your system you may also want to remove the .gem folder if it exists. Once you are finished, make sure to log out/back into your system for all changes to take effect. That’s it!!! See ya!!!

Ruby on Rails Better Errors Gem

Ruby on Rails Better Errors Gem

Better Errors replaces the standard Rails error page with a much better and more useful error page. It is also usable outside of Rails in any Rack app as Rack middleware.

Instead of a plain default error page, Better Errors will display a full interactive stack trace with source code inspection.

If you also include the companion binding_of_caller2 gem into your application Better Errors will be able to also let you inspect local and instance variables and even embed a full REPL into every stack frame of your error page backtrace. Of course you should only ever do that in a development environment.

To use it simply add the following to your Gemfile:

1
2
3
4
group :development do
  gem "better_errors"
  gem 'binding_of_caller'
end

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