Integration of Google reCaptcha with Rails application

ReCaptcha is a powerful captcha service to be use with a form to stop spam. This blog demonstrates the use of reCaptcha in rails application. Here I have used the ruby version 1.9.3 and Rails version 3.2.8.

Environment

  • Ruby version – 1.9.3
  • Rails – 3.2.8

Step#1

Create an account with Recaptcha “http://www.google.com/recaptcha” and register your site name with your google account to retrieve the public and private key that will be used later on the application

Step#2 

Installation of Recaptcha

  • Gem
  • Open your Gemfile and add this code
gem 'recaptcha', :require => 'recaptcha/rails'
  • Plugin
  • rails plugin install git://github.com/ambethia/recaptcha.git

Step#3

Create a file named recaptcha.rb in RAILS_ROOT/config/initializer and fill it with these codes

ENV['RECAPTCHA_PUBLIC_KEY'] = 'youractualpublickey' ENV['RECAPTCHA_PRIVATE_KEY'] = 'youractualprivatekey'

Step#4

Usages Open your views file and add this code

<%= recaptcha_tags %>

Step#5

Validation In controller, you can check the captcha validation by the following

if @model.save && verify_recaptcha(:model => @developer, :message => "Oh! It's error with reCAPTCHA!") #captcha is valid else #captcha is invalid end

Implementing Sortable Columns in Rails through Helper

Use of a sortable column in a listing view. For an example there is a list of “Programs”

Step# 1

  • Here our controller is named as “Programs” and the model is named as “Program”
  • Add the following helper methods to the controller
class ProgramsController < ApplicationController
helper_method :sort_column, :sort_direction
protected
def sort_column
Program.column_names.include?(params[:sort]) ? params[:sort] : "position"
end
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
def your_custom_action
end
end

Step# 2

  • In Helper class of “Program” add the following codes
module ProgramsHelper
def sortable(column, title = nil)
title ||= column.titleize
active = column == sort_column
ascending = active && sort_direction == 'asc'
direction_html = ascending ? ' ▲ ' : ' ▼ ' if active
css_class = active ? "current #{sort_direction}" : nil
direction = ascending ? "desc" : "asc"
link_to(title, { :sort => column, :direction => direction }, :remote => true, :class => css_class) << raw(direction_html)
end
end

 

Step# 3

  • In the view (index.html.slim) file add the helper method “sortable” in the columns you want to sort
  • Please note: Here slim is used for the view pages
#main
table style="text-align:left;"
tr
th align="left" = sortable "name"
th align="left" = sortable "created_at", "Added"
th align="left" = sortable "subscription_level_id", "Subscription"
th align="left" = sortable "rating_average", "Rating"
- programs.each do |program|
= content_tag_for :tr, program, 'row_for' do
td= link_to program.name, program_url(program)
td.attribute= program.created_at.strftime("%B %Y")
td.attribute= program.subscription_level.name.capitalize if program.subscription_level
td.attribute= ratings_for program
.pagination_container style="padding-bottom:20px;"
= will_paginate programs

How to use Nested Attributes in Rails 3 Forms

For example, say we want to add multiple addresses(attributes) having many fields inside a create/edit employee form

Step# 1

  •         Create a model named Employee
  •         Create another model named Address
  •         Add the following relationship in Employee model
class Employee < ActiveRecord::Base
has_many :addresses, :dependent => :destroy
accepts_nested_attributes_for :addresses, :reject_if => lambda { |a| a[:city].blank? }
end
  •    Nested attribute form rejects if the city field of the address is blank

Step# 2

  •        In Employees controller add the following in the “new” action
def new
@employee = Employee.new
@employee.addresses << Address.new
end

Step# 3

  •         In the view file add the following inside the form attribute
<%= form_for @employee, :html => { :multipart => true, :id => 'new-employee' } do |f|
<%= f.label :name, 'Name' %>
<%= f.text_field :name %>
 
<% end %>