How to shorten URL using “bitly.com” in Rails 3.x

rorURL shortening is a technique on the World Wide Web (WWW) in which a Uniform Resource Locator (URL) may be made substantially shorter in length and still direct to the required page.

This is achieved by using an HTTP Redirect on a domain name that is short, which links to the web page that has a long URL. This is especially convenient for messaging technologies such as Twitter and Identical which severely limit the number of characters that may be used in a message.

Many web developers pass descriptive attributes in the URL to represent data hierarchies, command structures, transaction paths or session information. This can result in URLs that are hundreds of characters long and that contain complex character patterns. Such URLs are difficult to memorize and manually reproduce. As a result, long URLs must be copied-and-pasted for reliability. Thus, short URLs are more convenient for websites.

Step# 1

  • To begin with, create an account at bit.ly “
  • Get your API key by the following URL

“http://bit.ly/account/your_api_key/”

Step# 2

  • In rails 3.x

Write the following gems in your gemfile

gem 'bitly'
  • Run “bundle install”

Step# 3

Add the following code in your controller

require 'bitly'

Step# 4

Bitly recently released their version 3 API. From this 0.5.0 release, the gem will continue to work the same but also provide a V3 module, using the version 3 API. The standard module will become deprecated, as Bitly do not plan to keep the version 2 API around f orever.

To move to using the version 3 API, call in you top of the controller:

Bitly.use_api_version_3

Step# 5

To shorten a URL

bitly = Bitly.new('your-bitly-user-id','your-bitly-api-key') page_url = bitly.shorten('your-url') shorten_url = page_url.short_url

It will generate the bitly URL similar to “http://bit.ly/7BWXcQ”

Creating an Engine on Refinery CMS

Refinerycms

‘Engines’ are nothing but ‘plug-ins’ which adds up extended functionality to the existing Refinery application. Engines installs in the “vendor/extensions” folder in a refinery app.

Engines will create a tab in the Admin panel of the Refinery CMS to control the information on the engine.This example demonstrates creating an engine in an existing refinery app. The environments used are Ruby 1.9.3, Rails 3.2.8 & Refinery cms 2.0.8.

Step#1

To create an engine, just execute the below command

rails generate refinery:engine engine_name attribute:type attribute:name

NB: The engine name should be in singular which will generate the structure in plural form.
For example we want a FAQ engine for our CMS which will be controlled by CMS admin

rails generate refinery:engine MyFaq question:string answer:text

Running the above command will create a new folder “extensions” under “vendor” directory and in the “extensions” the new engine “my_faqs” will be created.

Step#2

After that run the below commands to make it executable

bundle install
rails generate refinery:my_faqs
rake db:migrate
rake db:seed

Step#3

Restart the server to get the effect. You will find the new tab “My Faqs” has been added both in the menu section of the user section and admin section.

Login as Admin to manage your FAQs

How to customize an engine during creation?

Creating the engine with a namespace

rails g refinery:engine MyFaq title description:text --namespace FAQ

Creating the engine by skipping the frontend pages

It will add menu and form page in the admin section only. User section will be omitted

rails g refinery:engine MyFaq title description:text --skip-frontend

Customizing Error Messages In RAILS

In every application regardless of its complexity we require to customize error messages to make more sense. There are several ways to achieve it in Rails 3 and in Rails 2.3.x which are mentioned specifically and that can be handled either in models or controllers or helpers.

Solution# 1:

If it is needed to be handled in model and message need to be have customized instead of the attribute name. Like if the attribute name is “name” but you want to display messages “Employee name cannot be blank” then we have to install “custom-err-msg” plug-in.

This plugin gives you the option to not have your custom validation error message prefixed with the attribute name. Ordinarily, if you have, say:

validates_acceptance_of : terms, :message => 'Please accept the terms of service'

You’ll get the following error message: Terms Please accept the terms of service

This plugin allows you to omit the attribute name for specific messages. All you have to do is begin the message with a ‘^’ character. Example:

validates_acceptance_of :accepted_terms, :message => '^Please accept the terms of service'

step# 1

To install the ”custom-err-msg” plug-in you have to use the command.

“ruby script/plugin install https://github.com/gumayunov/custom-err-msg.git”

If you are facing problem by installing the plugin then clone it and just copy the folder (”gumayunov-custom-err-msg-640db42”) inside “Vendor/plugin/” folder

step# 2

In view file just display it as mentioned below:

Similarly, it can use in other places like,

validates_presence_of :claim_no, :message => "^Work Order/Claim number cannot be blank!"

The plugin also lets you use procs instead of strings.

Example:

validates_acceptance_of :accepted_terms, :message => Proc.new {|service| "You must accept the terms of the service #{service.name}" }

The above plug-in usage can be avoided by declaring alias for each attribute as mentioned below.
You should have a file named config/locales/en.yml, if not simply create one. There you can add your own custom names.

en:
activerecord:
models:
order: "Order"
attributes:
order:
b_name: "Business Name"

This will replace your attribute “b_name” with “Business Name”

Your Order model in app/models/order.rb should look like:

class Order < ActiveRecord::Base
validates :b_name, :presence => true

The error message will be displayed like

Business Name cannot be blank

Solution# 3:

Another way is to define a method and an error message inside the method in the model.

Class Employee < ActiveRecord::Base
validate :zip_must_be_valid
def zip_must_be_valid
unless zip.map(&:valid?).all?
errors.add_to_base " zip code is invalid"
end
end
end

We can also customize the error messages in Controllers.
Suppose “First Name” cannot be blank to be checked. Then use below code to check for it and show customized messages

if(params[:employee][:first_name].nil?)
flash[:error] = "First name should not be blank.n"
end

Subsequently, if it is required to add other messages to the above for other attributes then it can be written as,

if(params[:employee][:address].nil?)
flash[:error] += Address should not be blank.n"
end

Solution# 5

Customization of error messages can be done in controllers by adding messages to the existing error object’s method “add_to_base”.

if email_data[:"email_no_#{i}"] != "" && email_data[:"email_no_#{i}"] !~ /^([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i
valid_params = false
@company_info_new.errors.add_to_base( "Invalid Email Id!" )
End

In views it can be displayed by writing below code:

0 %>
nil, :message => nil >

Solution# 6

The customization that can be handled in views using

“error_message_on” helpers (Rails 2.3.8)”

In case you wish to show one error message in a specific location that relates to a specific validation then use “error_message_on” helper. You might have used “error_message_on” to display field-specific error messages. Here is an example that would display an error message on a name field:

Solution# 7

You can also use “error_message_on”(Rails 2.3.8) to display non-field-specific error messages.

class User < ActiveRecord:Base
validate :user_is_active
private
def user_is_active
if self.is_active != true
errors.add : user_is_active, 'User must be active to continue'
end
end
end

Now, to display this custom validation error message with “error_message_on”, we simply need to reference “:user_is_active” when we call the helper. Consider this implementation:

Solutions# 8

class User < ActiveRecord::Base validates_presence_of :email validates_uniqueness_of :email validates_format_of :email, :with => /^[wd]+$/ :on => :create, :message => "is invalid"
end

In Rails 3 it’s possible to call a validate method and pass it a hash of attributes to define the validations instead of defining each validation separately as mentioned above.
/app/models/user.rb

class User < ActiveRecord::Base validates :email, :presence => true,
:uniqueness => true,
:format => { :with => /^([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i }
end

In the User model we’re still validating that the field has a value and that the value is unique. For validating the format there are a number of options we can pass so we use a secondary hash to define those.

We can supply any number of validations for an attribute with a single command. While this is useful it can become cumbersome if there are a large number of validations but for most situations, it works nicely.

We can make the “:format” option more concise and clean it up a little. We often want to validate email addresses and having the same long regular expression in each validator is a little ugly and introduces repetition into the code. We can extract this out into a separate validation by creating a new class in our application’s /lib directory. We’ll call the file email_format_validator.rb.

class EmailFormatValidator < ActiveModel::EachValidator
def validate_each(object, attribute, value)
unless value =~ /^([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i object.errors[attribute] << (options[:message] || "is not formatted properly")
end
end
end

The EmailFormatValidator class inherits from ActiveModel:: EachValidator. We have to define one method in the class “validate_each”, that takes three parameters called object, attribute and value. The method then checks that the value matches the regular expression we’re using to validate an email address and if not it will add the attribute to the objects errors.

We can use this technique to define any kind of validation we like. Now that we have our custom validator we can update the validator in the “User” model to use it.
/app/models/user.rb

class User < ActiveRecord::Base
validates :email,
:presence => true,
:uniqueness => true,
:format => { :with => /^([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i }
end

Having an email_format key in the “validates” hash means that the validator will look for a class called email_format_validator and passes the validation behavior into the custom class that we just wrote.
If we try to create a new user now and enter an invalid email address we’ll see the expected error message.

If you have some trick to share, do it in the comments.

How to add AJAX Pagination using jQuery in Rails3

Ruby_on_railsAjax pagination will do the same functionality of pagination without refreshing the page. It calls the action through jQuery to display the results per page.

This example demonstrates the implementation of ajax pagination in Rails3. However the same can be used with Rails2.3.x.

Remember to add jQuery to your paths.

Step#1

Add the following gem to your Gemfile

gem 'will_paginate'
Run bundle install

Step#2

Include the following code in the controller you want to paginate, For example, I have used Posts controller.

class PostsController < ApplicationController
  def index
    @posts = Post.paginate(page: params[:page], per_page: 10)
  end
end

Step#3

Add this in the view “posts/index.html.erb” file

<div id=”post_id”>
<%=render partial:’posts’%>
</div>

Encapsulate the order list in the partial view “posts/_posts.html.erb”

<ul>
<% @posts.each do |post|%>
<li>
<!-- Show post data -->
</li>
<% end %>
</ul>
<% = will_paginate(@posts,:id=>”ajax_paginate”)%>
 
<script>
 
$(document).ready(function() {
$(“#ajax_paginate”).find(“a”).each(function(){
var linkElement = $(this);
var paginationURL = linkElement.attr(“href”);
linkElement.attr({“url”:paginationURL, “href”: ”#”});
linkElement.click(function(){
$(“#post_id”).html(‘<div align= “center”><br/>
<img src=”/images/loader.gif”/></div>’)
$(“#post_id”).load($(this).attr(‘url’));
Return false;
});
});
});
 
</script>

The last line “”ajax_paginate”) %>” will generate your pagination links

Voila, You are done!

Polymorphic Associations in Rails3

ror31In polymorphic associations, a model can belong to more than one model, on a single association.

Here is an example where a model is associated with two other models in Rails3. For example we have Events and Article model which have comments. So the “Comment” model is common between the “Event” and “Article” model. Here are the steps to implement the polymorphic association between these three models.

Step#1
Let’s create a resource “Comment” by rails generator.

rails g scaffold Comment content:text

Step#2

Add associations in the models as below

Comment model:

class Comment < ActiveRecord::Base
attr_accessible :commentable_id, :commentable_type, :content
belongs_to :commentable, :polymorphic => true  #Now, it is acted as polymorphic
end

Event model:

class Event < ActiveRecord::Base
attr_accessible :name
has_many :comments, :as => :commentable
end

Article model:

class Article < ActiveRecord::Base
attr_accessible :name
has_many :comments, :as => :commentable
end

Step#3

Add the following attributes in the migration files of the comment model

Look for newly created file under “db/migrate” folder

class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :content
t.references :commentable, :polymorphic => true
t.timestamps
end
end
end

Then execute rake db: migrate in the command line

Step#4

Add nested resources inside the “config/routes.rb” file

resources :events  do
resources :comments
end
resources :articles do
resources :comments
end

Step#5

Add link to add new comments in view page of article and events as follows

In “/app/views/events/show.html.erb”

<%= link_to 'New comment', new_event_comment_path(@event)  %>

In /app/views/articles/show.html.erb

<%= link_to 'New comment', new_article_comment_path(@article)  %>

Step#6

Changing the form_for tag in new comment page

In “/app/views/comments/_form.html.erb”

Before

<%= form_for (@comment) do |f| %>

After

<%= form_for [@commentable, @comment] do |f| %>

Add following codes in both “Articles” & “Events” controllers to get the comments individually

In “/app/controllers/events_controller.rb”

def show
@event = Event.find(params[:id])
@comments= @event.comments #added to view all the comments for the selected event
respond_to do |format|
format.html # show.html.erb
format.json { render json: @event }
end
end

In “/app/controllers/articles_controller.rb”

def show
@article = Article.find(params[:id])
@comments= @article.comments #added to view all the comments for the selected article
respond_to do |format|
format.html # show.html.erb
format.json { render json: @article }
end
end

Step#8

Add the following codes to “Comments” controller to creating a comment

In “/app/controllers/comments_controller.rb”

class CommentsController < ApplicationController
def new
@commentable = find_commentable
@comment = Comment.new
end
def create
@commentable = find_commentable
@comment = @commentable.comments.build(params[:comment])
if @comment.save
flash[:notice] = "Successfully created comment."
redirect_to :id => nil
else
render :action => 'new'
end
end
 
private
 
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
end

Now the comment model will work as a polymorphic association between article and event model.

Usage of PDFKit with Rails 3.2.8 and Ruby 1.9.3

PDFkit is a powerful library which generates PDF from HTML + CSS. It uses “wkhtmltopdf” on the back-end which renders HTML using Webkit. Here is a simple example which describes the installation of “wkhtmltopdf” and usages of pdfkit. I have used rails 3.2.8 and ruby 1.9.3 as my environment.

Step-1:

Install the “wkhtmltopdf” library

Download the “wkhtmltopdf” library from the link
http://code.google.com/p/wkhtmltopdf/

Windows

  • Download the exe file and install it.
  • Remember the installation path

Linux

  • Download the binary for your architecture at the http://code.google.com/p/wkhtmltopdf/downloads/list
  • Extract the file to a directory that is in your PATH, such as /opt or /usr/local/bin and run from there.

For Debian/Ubuntu use the following command:

apt-get install wkhtmltopdf

Step-2: Installing PDFKit

In your bundle file write

gem 'pdfkit'

Then install

bundle install

Step-3: Configuration of PDFKit

Create a new file “pdfkit.rb” in “config/initializers/” path and write the following

If you are in windows then you need to give the path to the exe file generated after installation. If you are in linux and the path is set as the default path then you don’t need to give the path.

PDFKit.configure do |config|
config.wkhtmltopdf = 'C:Program Fileswkhtmltopdfwkhtmltopdf .exe'
config.default_options = {
:page_size => 'Legal',
:print_media_type => true
}
# config.root_url = "http://localhost" # Use only if your external hostname is unavailable on the server.
end

Step-4: Middleware Setup

Write the following in the “config/application.rb

require 'pdfkit'
 
config.middleware.use PDFKit::Middleware
config.threadsafe!

Step-5: Usages

Creating PDF in a file path

Now to generate the pdf file by writing down the following codes on one of your controller actions

kit = PDFKit.new"<h1>Hello</h1><p>This is PDF!!!</p>"
file_path = your_file_path
pdf = kit.to_file file_path

Now you can find the PDF file being generated on the file path.

Displaying PDF on browser

<p id="pdf_link"><%= link_to "Download Invoice (PDF)", order_path(@order, :format => "pdf") %></p>

Your PDF will be displayed on the browser.

You can also add “.pdf” to any of our application’s URLs to get a PDF version of that page.