by sandipransing
If your application is currently on any version of Rails 2.1.x, The following changes needs to be done for upgrading your application to Rails 2.3.11
1. First install Rails version 2.3.11
gem install rails -v2.3.11
2. Freeze app ruby gems
rake rails:freeze:gems
Hopefully it should work for you but it gave me following error
undefined method `manage_gems' for Gem:Module
3. Create sample rails 2.3.11 app
rails _2.3.11_ testsapp
Now, Copy all missing "config/initializers/*" files from new "testapp to the application that to be upgraded.
cp testapp/config/initializers/* config/initializers
4. Change Rails version inside environment.rb to Rails 2.3.11
# Specifies gem version of Rails to use when vendor/rails is not present
RAILS_GEM_VERSION = '2.3.11'
5. Rename app/controllers/application.rb file to app/controllers/application_controller.rb
OR
rails:update:application_controller
6. Start rails server and fix the issues one by one.
ruby script/server
Read More…
by sandipransing
Previous post explains on mongoid document array field and rails form implementation
Below example shows rails form integration of array field of embedded mongoid document
consider scenario, student embeds one family who has many assets
class Student
include Mongoid::Document
field :name
field :phone
embeds_one :family
validates_associated :family
accepts_nested_attributes_for :family
end
class Family
include Mongoid::Document
ASSETS = ['flat', 'car', 'business', 'bunglow', 'cash']
field :members, type: Integer
field :assets, type: Array
field :religon
embedded_in :student
end
Brief controller code
class StudentsController < ApplicationController
def new
@student = Student.new
@student.family ||= @student.build_family
end
def create
@student = Student.new(params[:student])
@student.family.assets.reject!(&:blank?)
if @student.save
[...]
else
render :action => :new
end
end
end
view form will look like-
= form_for(@student) do |s|
= s.text_field :name
= s.text_field :phone
- s.fields_for :family do |f|
= f.text_field :members
= f.text_field :religion
- Family::ASSETS.each do |asset|
/Here f.object_name #=> student[family]
= f.check_box :assets, :name => "#{f.object_name}[assets][]", asset
Read More…
by sandipransing
rails-uri module provide us with url manipulation methods
Parse string url
url = URI.parse('http://funonrails.com/search/label/rails3')
url.host #=> "http://funonrails.com"
url.port #=> 80
URL with Basic Authentication
url = URI.parse('http://sandip:2121@funonrails.com/search/label/rails3')
url.user #=> "sandip"
url.password #=> "2121"
Extracting urls form string paragraph
URI.extract('http://funonrails.com is rails blog authored by http://sandipransing.github.com contact mailto://sandip@funonrails.com')
#=> ["http://funonrails.com", "http://sandipransing.github.com", "mailto://sandip@funonrails.com"]
Split & Join URI
URI.split('http://sandip:2121@funonrails.com/search/label/rails3')
#=> ["http", "sandip:2121", "funonrails.com", nil, nil, "/search/label/rails3", nil, nil, nil]
<=> [Scheme, Userinfo, Host, Port, Registry, Path, Opaque, Query, Fragment]
URI.join('http://funonrails.com','search/label/rails3')
#=> #
Escape & Unescape alias encode/decode URI
URI.escape('http://funonrails.com/search/?label=\\rails\3')
URI.encode('http://funonrails.com/search/?label=\\rails\3')
#=> "http://funonrails.com/search/?label=%5Crails%5C3"
URI.unescape("http://funonrails.com/search/?label=%5Crails%5C3")
URI.decode("http://funonrails.com/search/?label=%5Crails%5C3")
#=> "http://funonrails.com/search/?label=\\rails\\3"
Match urls using regular expressions
"http://funonrails.com/search/label/rails3".sub(URI.regexp(['search'])) do |*matchs|
p $&
end
#=> "http://funonrails.com/search/label/rails3"
Getting requested url inside rails
request.request_uri
request.env['REQUEST_URI']
Getting previous page url inside rails
request.referrer
Read More…
by sandipransing
Paypal standard website payment service allows online payment transactions for websites.
Before implementing payments inside rails app needs to have following things in place-
1. Register Paypal sandbox account
2. Paypal Merchant account api credentials i.e. login, password, signature, application_id
3. Paypal Buyer account creds to test payments
Bundle Install
# Gemfile
gem 'activemerchant
Gateway config
# config/gateway.yml
development: &development
mode: test
login: rana_1317365002_biz_api1.gmail.com
password: '1311235050'
signature: ACxcVrB3mFChvPIe8aDWQlLhAPN46oPBQCj7rJWPza6CDZmBURg.
application_id: APP-76y884485P519543T
production:
<<: *development
test:
<<: *development
New Payment Form
= form_for @payment ||= Payment.new, :url => pay_bill_url, :html => {:id => :payForm} do |p|
= p.text_field :amount
= p.submit 'Pay'
Generate & Migrate Payment Model
rails g model payment status:string amount:float transaction_number:string
rake db:migrate
Payment Model
# app/models/payment.rb
class Payment < ActiveRecord::Base
PROCESSING, FAILED, SUCCESS = 1, 2, 3
validates :amount, :presence => true, :numericality => { :greater_than => 0 }
def self.conf
@@gateway_conf ||= YAML.load_file(Rails.root.join('config/gateway.yml').to_s)[Rails.env]
end
## Paypal
def setup_purchase(options)
gateway.setup_purchase(amount * 100, options)
end
def redirect_url_for(token)
gateway.redirect_url_for(token)
end
def purchase(options={})
self.status = PROCESSING
#:ip => request.remote_ip,
#:payer_id => params[:payer_id],
#:token => params[:token]
response = gateway.purchase(amt, options)
if response.success?
self.transaction_num = response.params['transaction_id']
self.status = SUCCESS
else
self.status = FAILED
end
return self
rescue Exception => e
self.status = FAILED
return self
end
private
def gateway
ActiveMerchant::Billing::Base.mode = auth['mode'].to_sym
ActiveMerchant::Billing::PaypalExpressGateway.new(
:login => auth['login'], :password => auth['password'],
:signature => auth['signature'])
end
def auth
self.class.conf
end
end
Billing routes
## Callback URL
match '/billing/paypal/:id/confirm', :to => 'billing#paypal', :as => :confirm_paypal
## Create payment
match '/billing', :to => 'billing#create', :as => :pay_bill
## Request URL
match '/billing/paypal/:id', :to => 'billing#checkout', :as => :billing
match '/billing/thank_you/:id', :to => 'billing#checkout', :as => :billing_thank_you Billing Controller
# app/controllers/billing_controller.rb
class BillingController < ApplicationController
before_filter :get_payment, :only => [:checkout, :paypal, :thank_you]
def create
@payment = Payment.new params[:payment]
if @payment.save
## Paypal Checkout page
redirect_to billing_url
else
render :action => :new
end
end
# ASSUMPTION # payment is valid i.e. amount is entered
def checkout
response = @payment.setup_purchase(:return_url => confirm_paypal_url(@payment), :cancel_return_url => root_url)
redirect_to @payment.redirect_url_for(response.token)
end
## CALL BACK
def paypal
@payment = @payment.purchase(:token => params[:token], :payer_id => params[:PayerID], :ip => request.remote_ip)
@payment.save
redirect_to thank_you_billing_url(@order)
end
private
def get_payment
@payment = Payment.find_by_id(params[:id])
@payment && @payment.valid? || invalid_url
end
end
Views
# app/views/billing/thank_you.html.haml
- if @payment.success?
%p The transaction is successfully completed
- else
%p The transaction failed
Read More…
by sandipransing
Authorize Net SIM gateway transaction skips merchant side creditcard details form and directs transaction to be take place on gateway server.
# Gemfile
gem 'authorize-net'
Register for authorize net sandbox account click herePayment gateway credentials
# config/gateway.yml
development: &development
mode: test
login: 9gdLh6T
key: 67fu45xw6VP92LX1
production:
<<: *development
test:
<<: *development
Generate & Migrate Payment Model
rails g model payment status:string amount:float transaction_number:string
rake db:migrate
SIM gateway methods extracted and added to payment model
# app/models/payment.rb
class Payment < ActiveRecord::Base
PROCESSING, FAILED, SUCCESS = 1, 2, 3
validates :amount, :presence => true, :numericality => { :greater_than => 0 }
def self.conf
@@gateway_conf ||= YAML.load_file(Rails.root.join('config/gateway.yml').to_s)[Rails.env]
end
def success?
self.status == SUCCESS
end
## Authorize :: SIM
def setup_transaction(options ={})
options.merge!(:link_method => AuthorizeNet::SIM::HostedReceiptPage::LinkMethod::POST)
t = AuthorizeNet::SIM::Transaction.new(
auth['login'], auth['key'], amount,
:hosted_payment_form => true,
:test => auth['mode']
)
t.set_hosted_payment_receipt(AuthorizeNet::SIM::HostedReceiptPage.new(options))
return t
end
def auth
self.class.conf
end
end
Payment routes
## Callback URL
match '/billing/:id/confirm', :to => 'billing#authorize', :as => :confirm_billing
## Request URL
match '/billing/:id', :to => 'billing#checkout', :as => :billing
match '/billing/:id/thank_you', :to => 'billing#thank_you', :as => :thank_you_billing
Billing controller
# app/controllers/billing_controller.rb
class BillingController < ApplicationController
helper :authorize_net
before_filter :get_order, :only => [:checkout, :authorize, :thank_you]
def checkout
# ASSUMPTION order is valid means amount is entered
@transaction = @order.setup_transaction(
{:link_text => 'Continue',
:link_url => confirm_billing_url(@order)})
end
## CALL BACK
def authorize
resp = AuthorizeNet::SIM::Response.new(params)
if resp.approved?
@order.status = Payment::SUCCESS
@order.transaction_num = resp.transaction_id
else
@order.status = Payment::FAILED
end
@order.save(:validate => false)
redirect_to thank_you_billing_url(@order)
end
private
def auth
Payment.conf
end
def get_order
@order = Payment.find_by_id(params[:id])
@order && @order.valid? || invalid_url
end
end
Views Forms
# app/views/billing/checkout.html.haml
= form_for :sim_transaction, :url => AuthorizeNet::SIM::Transaction::Gateway::TEST, :html => {:id => :authForm} do |f|
= sim_fields(@transaction)
:javascript
$(document).ready(function(){
$('#authForm').submit();
})
# app/views/billing/thank_you.html.haml
- if @order.success?
%p The transaction is successfully completed
- else
%p The transaction failed
Read More…
by sandipransing
Customizing default rails form builder to adopt for labels, input fields, errors, hints, etc. in order to build forms just in minutes
# app/helpers/app_form_builder.rb
class AppFormBuilder < ActionView::Helpers::FormBuilder
HELPERS = %w[check_box text_field text_area password_field select date_select datetime_select file_field collection_select state_select label calendar_date_select]
def self.create_tagged_field(method_name)
define_method(method_name) do |name, *args|
errs = object.errors.on(name.to_sym) if object && object.errors
# initialize some local variables
if args.last.is_a?(Hash)
label = args.last.delete(:label)
suffix = args.last.delete(:suffix)
klass = args.last.delete(:class)
req = args.last.delete(:required)
end
label = 'none' if method_name == 'hidden_field'
label ||= name.to_s.titleize
label = nil if label == 'none'
klass = klass ? [klass] : []
# Custom class if it exists
if method_name =~ /text_field|check_box|select/
klass << method_name
end
klass << 'f' #A default selector
klass << 'error' if errs.present?
klass = klass.join(' ')
# Required Field Notations
if req == 'all' || (req == 'new' && object.new_record?)
label << @template.content_tag(:span, :*, :class => :req)
end
suffix = @template.content_tag(:label, suffix) if suffix.present?
label = @template.content_tag(:label, label) if label.present?
errs = @template.content_tag(:span, errs.to_s, :class => :message) if errs.present?
reverse = true if method_name == 'check_box'
if reverse
content = "#{super} #{suffix} #{label} #{errs}"
else
content = "#{label} #{super} #{suffix} #{errs}"
end
@template.content_tag(:div, content, :class => klass)
end
end
HELPERS.each do |name|
create_tagged_field(name)
end
end
Read More…
by sandipransing
Authorize Net (AIM) method enables internet merchants to accept online payments via credit card.
Below post will show you how to integrate authorize net payment gateway inside rails app to accept online payments using activemerchant library.
# Gemfile
gem 'activemerchant', :require => 'active_merchant'
Register for authorize net sandbox account click here
Payment gateway credentials
# config/authorize_net.yml
development: &development
mode: test
login: 9gdLh6T
key: 67fu45xw6VP92LX1
production:
<<: *development
test:
<<: *development
Payment & creditcard form
# app/views/payments/new
= form_for @payment, :url => payments_url do |f|
= f.text_field :amount
= fields_for :creditcard, @creditcard do |cc|
= cc.text_field :name
= cc.text_field :number
= cc.select :month, Date::ABBR_MONTHNAMES.compact.each_with_index.collect{|m, i| [m, i+1]}, {:prompt => 'Select'}
= cc.select :year, Array.new(15){|i| Date.current.year+i}, {:prompt => 'Select'}
= cc.text_field :verification_value
= f.submit 'Pay'
Payments Controller
# app/controllers/payments_controller.rb
class PaymentsController < ApplicationController
def new
@payment = Payment.new
@creditcard = ActiveMerchant::Billing::CreditCard.new
end
def create
@payment = Payment.new(params[:payment])
@creditcard = ActiveMerchant::Billing::CreditCard.new(params[:creditcard])
@payment.valid_card = @creditcard.valid?
if @payment.valid?
@payment = @payment.process_payment(@creditcard)
if @payment.success?
@payment.save
flash[:notice] = I18n.t('payment.success')
redirect_to payments_url and return
else
flash[:error] = I18n.t('payment.failed')
end
end
render :action => :new
end
end
Generate & Migrate Payment Model
rails g model payment status:string amount:float transaction_number:string
rake db:migrate
Payment Model
# app/models/payment.rb
class Payment < ActiveRecord::Base
PROCESSING, FAILED, SUCCESS = 1, 2, 3
validates :valid_card, :inclusion => {:in => [true], :message => 'Invalid Credit Card'}
validates :amount, :presence => true, :numericality => { :greater_than => 0 }
def process_payment(creditcard)
ActiveMerchant::Billing::Base.mode = auth['mode'].to_sym
self.status = PROCESSING
response = gateway.purchase(amount * 100, creditcard)
if response.success?
self.transaction_number = response.subscription_id
self.status = SUCCESS
else
self.status = FAILED
end
return self
rescue Exception => e
self.status = FAILED
return self
end
def success?
self.status == SUCCESS
end
private
def gateway
ActiveMerchant::Billing::AuthorizeNetGateway.new(
:login => auth['login'],
:password => auth['key'])
end
def auth
@@auth ||= YAML.load_file("#{Rails.root}/config/authorize_net.yml")[Rails.env]
end
end
Read More…
by sandipransing
Below extensions to active record base simplifies its usage while coding.
# config/initializers/core_extensions.rb
class ActiveRecord::Base
def self.pagination(options)
paginate :per_page => options[:per_page] || per_page, :page => options[:page]
end
def self.options_for_select(opts={})
opts[:name] ||= :name
opts[:attr] ||= :id
opts[:prompt] ||= 'Please Select'
all.collect{|c| [c.send(opts[:name].to_sym), c.send(opts[:attr].to_sym)]}.insert(0, [opts[:prompt], nil])
end
end
Usage
class Student< ActiveRecord::Base
#attributes #=> name, age
end
##
Student.pagination({:page => 10})
Student.pagination({:per_page => 2, :page => 2})
Student.options_for_select
Student.options_for_select({:prompt => 'Please select'})
Student.options_for_select({:name => :age})
Read More…
by sandipransing
Scopes are partial query conditions to database queries. scopes are always prefixed to class finders. There are several ways to use scopes inside rails models.
# 1. Scope defined below gets loaded while class definition loads
scope :active, where(:active => true)
scope :archived, where(:archived => true, :post_type => :general)
# 2.Dynamic scopes needs to be always defined inside lambda
scope :not_expired, lambda { where('expiry_date <= ?', Date.today) }
# 3.Combining scopes
scope :visible, published.not_expired
# 4. Passing parameters to scopes
# avoid below
scope :created_by_user, lambda {|user|
where('user_id = ?', user)
}
# use this
scope :created_by_user, lambda {|user|
where(:user_id => user)
}
# 5. passing multiple parameters
# avoid below
scope :made_between, lambda{|from, to|
where('created_date >= ? and created_date <= ?', from, to)
}
# use this
scope :made_between, lambda{|from, to|
where('created_date >= :from and created_date <= :to', :from => from, :to => to)
}
# 6. associations inside scope (joins and includes)
# below will perform eager loading effective when rendering posts with comments
scope :with_user_comments, lambda{|user|
includes(:comments).where('comments.user_id = ?', user)
}
# faster
# also can be done as post.comments.where(:user_id => user)
scope :with_user_comments, lambda{|user|
joins(:comments).where('comments.user_id = ?', user)
}
So, at last would suggest making use of symbols when there are multiple parameters to scopes and make maximum use of scopes rather than having where conditions everywhere :)
Read More…
by sandipransing
Heroku is readonly file system hence write operations can only be done inside tmp directory.
Asset compilation on heroku can be handled in different ways
#1. compiling locally and placing inside assets directory
RAILS_ENV=production bundle exec rake assets:precompile
#2. It compiles assets while slug compiles
#3. Run time asset compilation
# It compiles assets for every rails request if it notifies assets got modified
# config/application.rb
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
config.assets.prefix = Rails.root.join('tmp/assets').to_s
# config/environments/production.rb
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = true
Note: write operation made inside tmp directory can not make any guarantee of being persisted hence be careful while using.
Read More…
by sandipransing
Install RVM first
bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvminstaller)
rvm list known
# MRI Rubies
[ruby-]1.8.6-head
[ruby-]1.8.7[-p352]
[ruby-]1.9.3-head
ruby-head
# JRuby
jruby-1.2.0
jruby-head
# Rubinius
rbx-1.0.1
rbx-2.0.0pre
# Ruby Enterprise Edition
ree-1.8.6
ree-1.8.7-head
Install ruby 1.9.3
rvm install 1.9.3-head
rvm gemset create rails311
rvm use 1.9.3-head@rails311 --default
gem install rails -v3.1.1 --no-rdoc --no-ri
gem install heroku
gem install rb-readline
Create new rails project
rails new cdc -m http://railswizard.org/b22092a4358bbebb3a46.rb -J -T
Heroku Deployment Done
http://railsblank.heroku.com/ (production)
Local System nginx-passenger setup
gem install passenger
rvmsudo passenger-install-nginx-module
If you find pcre download error then make sure you libpcre-dev pkg
installed on your system otherwise install it and re-run
sudo apt-get install libpcre3-dev
Nginx Configuration
http {
passenger_root /home/sandip/.rvm/gems/ruby-1.9.3-head@rails311/gems/passenger-3.0.9;
passenger_ruby /home/sandip/.rvm/wrappers/ruby-1.9.3-head@rails311/ruby;
server {
listen 80;
server_name railsblank.local;
root /home/sandip/railsblank/public;
rails_env development;
passenger_enabled on;
}
git source code
git clone git://github.com/sandipransing/rails_blank.git
Read More…
by sandipransing
Stepwise guide to configure paperclip default options,
setting up aws-s3 storage in rails
Inside Gemfile
gem 'aws-s3', :require => 'aws/s3'
gem 'paperclip'
bundle install
Generate Print model to hold image
rails g model print image_file_name:string image_content_type:string image_file_size:string
rake db:migrate
Add s3 credentials to YML file
# config/s3.yml
access_key_id: DASDFG7KACNxIJdJXHPQ
secret_access_key: BnDrTnzCTX+R707wYEP/aCEqAsDFG7sgW
Add default paperclip attachment options to initializer
# Make sure to add host url inside config/environments
# HOSTNAME = 'http://lordganesha.com'
Paperclip::Attachment.default_options.merge!(
:storage => 's3',
:s3_credentials => YAML.load_file("#{Rails.root}/config/s3.yml"),
:path => ":class/:attachment/#{Rails.env}/:id/:style/:basename.:extension",
:default_url => "http://#{HOSTNAME}/images/paperclip/:class/:attachment/default.jpg",
:bucket => 'ganesha'
)
Add image attachment code to print model
# app/models/print.rb
class Print < ActiveRecord::Base
has_attached_file :image,
:styles => {:medium => ["400x400#", :jpg],
:thumb => ["100x100#", :jpg],
:slider => ["300x300#", :jpg]}
#validates_attachment_presence :image
validates_attachment_size :image, :less_than => 1.megabytes, :message => 'file size maximum 1 MB allowed'
validates_attachment_content_type :image, :content_type => ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/pjpeg', 'image/x-png']
end
Inside views
# inside new.html.haml
= form_for @print do
f.file_field :image
Read More…
by sandipransing
While developing rails application we often come across situation where you wanted different rails models connecting different tables of different databases.
Example: We are having ndnc model holding ndnc records associated with database ndnc.
Lets create ConnectionBase model that will connect to other databse 'ndnc' and that will be extended from ActiveRecordBase and put that inside library files
vi lib/connection_base.rb
class ConnectionBase < ActiveRecord::Base
establish_connection(
:adapter => "postgresql",
:username=> "sandip",
:password => "2121",
:database => "ndnc"
)
end
Wherever you wanted to connect to other database i.e. ndnc you can extend that particular model with ConnectionBase
class Ndnc < ConnectionBase
# connects to ndnc table of ndnc database
end
Please make sure library files are loaded while server startup
# vi config/application.rb
config.autoload_paths += %W(#{config.root}/lib)
Done !
In cases where you want only one particular model connecting other database table, you can put connection setting itself in that model.
Read More…
by sandipransing
Create new rails project
rails new demo -d mysql
Add active_scaffold gem to bundler
gem "active_scaffold_vho"
Run bundle install command
bundle install
Setup active scaffold to use jQuery
rails g active_scaffold_setup jquery
create public/javascripts/rails_jquery.js
create public/javascripts/jquery-ui-timepicker-addon.js
create config/initializers/active_scaffold.rb
insert app/views/layouts/application.html.erb
insert config/locales/en.yml
gsub app/views/layouts/application.html.erb
Generate active scaffold for resource city & zone
rails g active_scaffold City name:string
invoke active_record
create db/migrate/20110408123206_create_cities.rb
create app/models/city.rb
invoke test_unit
create test/unit/city_test.rb
create test/fixtures/cities.yml
route resources :cities do as_routes end
invoke active_scaffold_controller
create app/controllers/cities_controller.rb
create app/helpers/cities_helper.rb
invoke test_unit
create test/functional/cities_controller_test.rb
create app/views/cities
rails g active_scaffold Zone name:string city:references
invoke active_record
create db/migrate/20110408123531_create_zones.rb
create app/models/zone.rb
invoke test_unit
create test/unit/zone_test.rb
create test/fixtures/zones.yml
route resources :zones do as_routes end
invoke active_scaffold_controller
create app/controllers/zones_controller.rb
create app/helpers/zones_helper.rb
invoke test_unit
create test/functional/zones_controller_test.rb
create app/views/zones
Add Associations
class City < ActiveRecord::Base
end
class Zone < ActiveRecord::Base
belongs_to :city
end
class City < ActiveRecord::Base
has_many :zones
end
Migrate database
rake db:create
rake db:migrate
== CreateCities: migrating ===================================
-- create_table(:cities)
-> 0.1411s
== CreateCities: migrated (0.1413s) ==========================
== CreateZones: migrating ====================================
-- create_table(:zones)
-> 0.1507s
== CreateZones: migrated (0.1510s) ===========================
Start Server
rails s
Visit Browser URL: http://localhost:3000/cities
Snap
Read More…
by sandipransing
rails has built in number_to_currency helper which takes options like unit, delimeter, seperator which displays foreign currency correctly but somehow it is not best suited for indian currency.
Below is how we managed 2 years ago to display indian currency formatted properly with comma as seperator. personally i think it could be more better than what it is currently ;)
Number to indian currency(rupees) helper
module ApplicationHelper
def number_to_indian_currency(number)
if number
string = number.to_s.split('.')
number = string[0].gsub(/(\d+)(\d{3})$/){ p = $2;"#{$1.reverse.gsub(/(\d{2})/,'\1,').reverse},#{p}"}
number = number.gsub(/^,/, '') + '.' + string[1] if string[1]
# remove leading comma
number = number[1..-1] if number[0] == 44
end
"Rs.#{number}"
end
Sample Output for different combinations
>> helper.number_to_indian_currency(2000)
=> "Rs.2,000"
>> helper.number_to_indian_currency(2040)
=> "Rs.2,040"
>> helper.number_to_indian_currency(2040.50)
=> "Rs.2,040.5"
>> helper.number_to_indian_currency(2040.54)
=> "Rs.2,040.54"
>> helper.number_to_indian_currency(1222040.54)
=> "Rs.12,22,040.54"
After doing google today found from Piyush Ranjan's Blog that yes there are ways to optimize code.
Optimized Version
module ApplicationHelper
def number_to_indian_currency(number)
"Rs.#{number.to_s.gsub(/(\d+?)(?=(\d\d)+(\d)(?!\d))(\.\d+)?/, "\\1,")}"
end
end
Waw one line of code, Look at the beauty of regular expression :) Truely amazing !
Integrating Webrupee symbol
First include follwing stylesheet in your layout
//public/stylesheets/font.css
@font-face {
font-family: "WebRupee";
font-style: normal;
font-weight: normal;
src: local("WebRupee"), url("http://cdn.webrupee.com/WebRupee.V2.0.ttf") format("truetype"), url("http://cdn.webrupee.com/WebRupee.V2.0.woff") format("woff"), url("http://cdn.webrupee.com/WebRupee.V2.0.svg") format("svg");
}
.WebRupee {
font-family: 'WebRupee';
}
Improved Version of Helper
module ApplicationHelper
def number_to_indian_currency(number, html=true)
txt = html ? content_tag(:span, 'Rs.', :class => :WebRupee) : 'Rs.'
"#{txt} #{number.to_s.gsub(/(\d+?)(?=(\d\d)+(\d)(?!\d))(\.\d+)?/, "\\1,")}"
end
end
Usage
>> helper.number_to_indian_currency(400)
=> "<span class="WebRupee">Rs.</span> 400"
>> helper.number_to_indian_currency(5921, false)
=> "Rs. 5,921"
>> helper.number_to_indian_currency(9921)
=> "<span class="WebRupee">Rs.</span> 9,921"
This will show you rupees symbol on your webpages.
Read More…
by sandipransing
While looking for accessing rails template tags to be accessed on rails console in order to examine whatever written needs to be correct, found that - rails template tags can be tested on rails console using helper object
module ApplicationHelper
def display_amount(amount)
number_to_currency amount, :precision => 0
end
end
Helpers on rails console
rails c
>> helper.text_field_tag :name, 'sandip'
=> "<input id="name" name="name" type="text" value="sandip" />"
>> helper.link_to 'my blog', 'http://funonrails.com'
=> "<a href=''http://funonrails.com>my blog</a>"
>> helper.display_amount(2000)
=> "$2,000"
isn't cool ? though it's not finished yet. we can include helper files on console and access custom helper methods too
>> include ActionView::Helpers
=> Object
>> include ApplicationHelper
=> Object
>> include ActionView::Helpers::ApplicationHelper^C
>> display_amount 2500
=> "$2,500"
Using same way one can make use helpers in rake tasks file. Make sure environment is getting loaded into rake task.
# lib/tasks/helper_task.rake
namespace :helper do
desc 'Access helper methods in rake tasks'
task :test => :environment do
include ActionView::Helpers
include ApplicationHelper
puts display_amount 2500 #=> "$2,500"
end
end
Accessing helpers in Action Mailers
class Notifier < ActionMailer::Base
add_template_helper(ApplicationHelper)
def greet(user)
subject "Hello #{user.name}"
from 'no-reply@example.com'
recipients user.email
sent_on Time.now
@user = user
end
# app/views/notifier/greet.html.erb
Hi <%= @user.try(:name)%>,
Greetings !!!
You have got <%= display_amount(3000) %>
Rails routes on rails console
rails c
>> app.root_url
=> "http://www.example.com/"
>> app.change_password_path
=> "/change/password"
>> app.change_password_url
=> "http://www.example.com/change/password"
Now you may have got requirement to access routes inside rake tasks. Here is the way to do that-
# lib/tasks/route_test.rake
namespace :routes do
desc 'Access helper methods in rake tasks'
task :test => :environment do
include ActionController::UrlWriter
default_url_options[:host] = "myroutes.check"
puts root_url #=> "http://myroutes.check"
end
end
Optionally you can set value of host parameter from action mailer host configuration using
default_url_options[:host] = ActionMailer::Base.default_url_options[:hos]
Attention: This is my preferred way to use helpers and routes when needed and there may have other choices to do same. Anyone having better approach please feel free to add your valuable comment. I will definitely incorporate that in further developments.
Got Easy, Cheers ;)
Read More…
by sandipransing
Delayed Job & Monit configuration
We were struggling through how to monit delayed_job from past few months because monit doesn't work seamlessly with delayed_job start/stop commands and finally we got able to monit delayed_job.
Here is our old configuration that wasn't working anyhow-
check process delayed_job with pidfile /home/sandip/shared/pids/delayed_job.pid
stop program = "/bin/bash -c 'cd /home/sandip/current && RAILS_ENV=production script/delayed_job stop'"
start program = "/bin/bash -c 'cd /home/sandip/current && RAILS_ENV=production script/delayed_job start'"
if totalmem > 100.0 MB for 3 cycles then restart
if cpu usage > 95% for 3 cycles then restart
After doing google & looking at stackoverflow, we found different solutions to work with but none of them found useful to me. :(
After reading google group someone (not remembering exactly) directed to write a init script for delayed_job server and that perfectly worked for me and my headache of self moniting delayed_job ended up ;)
Here is delayed_job init script
## /etc/init.d/delayed_job
#! /bin/sh
set_path="cd /home/sandip/current"
case "$1" in
start)
echo -n "Starting delayed_job: "
su - root -c "$set_path; RAILS_ENV=production script/delayed_job start" >> /var/log/delayed_job.log 2>&1
echo "done."
;;
stop)
echo -n "Stopping delayed_job: "
su - root -c "$set_path; RAILS_ENV=production script/delayed_job stop" >> /var/log/delayed_job.log 2>&1
echo "done."
;;
*)
echo "Usage: $N {start|stop}" >&2
exit 1
;;
esac
exit 0
finally here is the working monit delayed_job configuration
check process delayed_job with pidfile /home/sandip/shared/pids/delayed_job.pid
stop program = "/etc/init.d/delayed_job stop"
start program = "/etc/init.d/delayed_job start"
if totalmem > 100.0 MB for 3 cycles then restart
if cpu usage > 95% for 3 cycles then restart
Thinking Sphinx monit configuration
check process sphinx with pidfile /home/sandip/shared/pids/searchd.pid
stop program = "/bin/bash -c 'cd /home/sandip/current && /usr/bin/rake RAILS_ENV=production ts:stop'"
start program = "/bin/bash -c 'cd /home/sandip/current && /usr/bin/rake RAILS_ENV=production ts:start'"
if totalmem > 85.0 MB for 3 cycles then restart
if cpu usage > 95% for 3 cycles then restart
Adhearsion (ahn) monit confiuration
check process ahn with pidfile /home/josh/shared/pids/ahnctl.pid
stop program = "/bin/bash -c 'cd /home/sandip/current && /usr/bin/ahnctl stop adhearsion'"
start program = "/bin/bash -c 'cd /home/sandip/current && /usr/bin/ahnctl start adhearsion'"
if totalmem > 100.0 MB for 3 cycles then restart
if cpu usage > 95% for 3 cycles then restart
Nginx monit configuration
check process nginx with pidfile /opt/nginx/logs/nginx.pid
start program = "/opt/nginx/sbin/nginx"
stop program = "/opt/nginx/sbin/nginx -s stop"
if cpu is greater than 70% for 3 cycles then alert
if cpu > 80% for 5 cycles then restart
if 10 restarts within 10 cycles then timeout
Read More…
by sandipransing
# in config/environment.rb
config.gem 'hoptoad_notifier'
# from your Rails root:
$ rake gems:install
$ rake gems:unpack GEM=hoptoad_notifier
$ script/generate hoptoad --api-key your_key_here
Read More…
by sandipransing
Testing restful & polymorphic resource routes on rails console
Open rails console
rails c # In rails 3
OR
ruby script/console
app object of URL
>> app
=> #<ActionController::Integration::Session:0xc164fac @result=nil, @status=nil, @accept="text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", @path=nil, @request_count=0, @application=#<ActionController::Dispatcher:0xc1644f8 @output=#<IO:0x85e34ec>>, @remote_addr="127.0.0.1", @host="www.example.com", @controller=nil, @https=false, @request=nil, @headers=nil, @cookies={}, @status_message=nil, @named_routes_configured=true, @response=nil>
Root URL
>> app.root_url => "http://www.example.com/"
Plural paths
>> app.calls_path => "/calls"
Singular routes
>> app.audio_call_path ActionController::RoutingError: audio_call_url failed
>> app.audio_call_path(1) => "/calls/1/audio"
>> app.audio_call_path(13) => "/calls/13/audio"
>> app.audio_call_path(13, :name => 'san') => "/calls/13/audio?name=san"
Polymorphic URLS
app.polymorphic_path(Call.first, :action => 'audio') => "/calls/253/audio"
>> app.polymorphic_path(Call.new) => "/calls"
Read More…
|