Saturday, August 21, 2010

Zipcode validation using geokit in rails

by sandipransing 0 comments
1.Install geokit gem
gem install geokit OR # Add following line inside rails initialize block Rails::Initializer.run do |config| config.gem 'geokit' end
And then run command
rake gems:install 2. Consider User model with zipcode as attribute field
include Geokit::Geocoders class User < ActiveRecord::Base set_table_name :users validate_presence_of :zipcode validate :request_zipcode_validation_using_geokit, :if => :zipcode private def request_zipcode_validation_using_geokit # Method request google api for location # if location found then zipcode is valid otherwise # add validation error on zipcode field # as it method contacts with google api and takes time # to return result, poll request only when zipcode gets # changed poll = true # default true for new objects if self.id ## this means already existing user and zipcode is valid last time # Hack to find where zipcode got modified or not # old_user = User.find self.id poll = false if old_user.zipcode == self.zipcode end # Actual requesting api to return location associated with zipcode if poll loc = MultiGeocoder.geocode(self.zip_code) end # Add Validation Error if location is not found errors.add(:zip_code, "Unable to geocode your location from zipcode entered.") unless loc.success end
Please note that same method can also be used to validate state, city and country.
Again we can use combination of fields to validate each other.
Like -
1. Based on country entered, state validation
2. Based on state, city validation
3. Based on city, zipcode validation
or
4. Based on zipcode and country, state and city validation

Here is another method to validate state and city based on zipcode and country.
Lets take example of 'US'
def request_state_and_city_validation_based_on_zipcode poll = true # default true for new objects if self.id ## this means already existing user and all attributes were valid last time # Hack to find any one of location attribute got modified # old_user = User.find self.id loc_attrs = %w{zipcode state city} # keep in mind country US is default assumed if loc_attrs.all? {|attr| self.attribute_for_inspect(attr) == old_user.attribute_for_inspect(attr)} self.poll = false end end # Actual requesting api to return location associated with zipcode if poll loc = MultiGeocoder.geocode("#{self.zip_code}, US") end # Add Validation Error if location is not found unless loc.success errors.add(:zip_code, "Unable to geocode your location from zipcode entered.") else # Validate state and city fields in compare to loc object returned by geocode errors.add(:state, "State doesn't matches with zipcode entered") if self.state != loc.state errors.add(:city, "City doesn't matches with zipcode entered") if self.city != loc.city end end
Note***
If you are subscriber of blog and not displaying post correctly. I request you to visit post on blog itself. Somehow style is not getting correctly in email. I will try to fix this problem asap.

Upcoming Posts
1. Geokit finders: Find locations in/within/beyond particular radius from specified location using acts_as_mappable plugin
2. Customizing authlogic for multiple sessions i.e. using different models for role based authentication.
Read More…

ActionMailer SMTP settings in rails

by sandipransing 0 comments
1. Add following line to rails environment file
ActionMailer::Base.delivery_method = :smtp
2. Include your email authentication
Create a ruby file called smtp_settings under config/initializers directory # config/initializers/smtp_settings.rb ActionMailer::Base.smtp_settings = { :address => "smtp.gmail.com", :port => 587, :authentication => :plain, :enable_starttls_auto => true, :user_name => "replies@gmail.com", :password => "_my_gmail_password_" } noTE** Keep starttls_auto always true
3. Create sample mailer in order to ensure that your settings are correct
Create a sample mailer
class EmailMailer < ActionMailer::Base def test_email from 'xx@gmail.com' to 'some@xx.com' subject "This is test email" message "It should get delivered to recipient inbox" end end 4. Test your configuration
EmailMailer.deliver_test_email
Read More…

Email attachments in ruby & rails

by sandipransing 0 comments
1. Add ActionMailer configuration in environment.
This configuration can be different for development and production.
# Include your application configuration below # You can set two configurations sendmail as well as smtp # To use SMTP you need to provide your email account credentials # Sendmail is a unix package that needs to be installed and configured while # using sendmail settings # Chances of getting emails into recipient's inbox are 100% for smtp settings # whereas sendmail needs some other configurations to be done before using. ActionMailer::Base.delivery_method = :smtp ActionMailer::Base.default_content_type = "text/html" 2. Create Mailer Model and add method to deliver email class EmailMailer < ActionMailer::Base def email_with_attachments(email, files=[]) # content type also can be set in environment file as # ActionMailer::Base.default_content_type = "text/html" @headers = {content_type => 'text/html'} @sent_on = Time.now @recipients = email.recipients @from = email.from @cc = FEEDBACK_RECIPIENT @subject = email.subject @body = email.message # attach files files.each do |file| attachment "application/octet-stream" do |a| a.body = file.read a.filename = file.original_filename end unless file.blank? end end 3. Email Model # This is the virtual model in rails which has no database table associated with it class Email < ActiveRecord::Base # It uses has_no_table plugin to create virtual model # This can also be done using following lines of code # # def self.columns() @columns ||= []; end # def self.column(name, sql_type = nil, default = nil, null = true) # columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null) # end # has_no_table #insert the names of the form fields here column :from, :string column :recipients, :string column :subject, :string column :message, :text column :call_id, :integer attr_accessor :is_subscribed #Validations goes here validates_presence_of :from, :message => "You dont have Email ID, you cannot continue!", :unless => "call_id.blank?" validates_format_of :from, :with => /^([^@]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i, :unless => "from.blank?" validates_presence_of :recipients validates_format_of :recipients, :with => /^([^@]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i, :message => "Invalid email format", :unless => "recipients.blank?" validates_presence_of :subject, :message end 4. Usage from console or controller # Here email is the valid object of email model # attachments is the area of files to be attached with email # In my case attachments are of kind of pdf files # you can specify type of attachment in your mailer method EmailMailer.deliver_email_with_attachements(email, attachments) if email.valid? Sending data stream as email attachments in rails.
In some cases, We need to dynamically generate files and you don't want to store them locally on file system instead you always like to email them from memory itself.
Here is the way to do that.
1. Mailer data stream as attachment method class EmailMailer < ActionMailer::Base def email_with_data_stream(email, data_stream=[]) @headers = {} @sent_on = Time.now @recipients = email.recipients @from = email.from @subject = email.subject @body = email.message # attach files data_stream.each do |data| attachment "application/octet-stream" do |a| a.body = data[0] a.filename = data[1] end unless data_stream.blank? end end end 2. Lets take example of pdf renderer. # Assume we have object of pdf attachements = [] data = pdf.render # Attach as many files you wanted. Be careful about email maximum size ;) attachments << data EmailMailer.deliver_email_with_data_stream(email, attachments)
Read More…

Saturday, August 7, 2010

Multiple sites hosting using radiant cms

by sandipransing 4 comments
There are almost 4 to 5 simple steps you need to followed before
getting multiple sites working using radiant cms
1. Setup radiant cms
first Install radiant gem
sudo gem install radiant

set 'radiant' under path
export PATH=$PATH:/var/lib/gems/1.8/gems/radiant-0.8.0/bin

Now, we have done with radiant installation.
Let's create new project..
$ radiant multisite -d mysql

$ cd multisite/

Edit database.yml
$ vi config/database.yml
development:
  adapter: mysql
  database: multisite_development
  username: root
  password: abcd
  host: localhost

Migrations
rake db:create

Run the database bootstrap rake task:
rake db:bootstrap
This task will destroy any data in the database. Are you sure you want
to continue? [yn] yes
...
Create the admin user (press enter for defaults).
Name (Administrator): admin
Username (admin): admin
Password (radiant): 
....
Select a database template:
1. Empty
2. Roasters (a coffee-themed blog or brochure)
3. Simple Blog
4. Styled Blog
[1-4]: 2
....

Now we are ready to start
script/server

Open following URL in browser.
http://localhost:3000

You should see site homepage. To manage site goto admin panel.

http://localhost:3000/admin

Now Lets start with multiple sites management
1) Clone multi_site extension into vendor/extensions of your project.
  cd vendor/extensions/
  git clone git://github.com/zapnap/radiant-multi-site-extension.git multi_site

2) Run the extension migrations.
  rake db:migrate:extensions

3) Run the extension update task.
  rake radiant:extensions:multi_site:update

4) Restart your server
And we are done with multisite installation, Open following URL in browser.

http://localhost:3000/admin/sites

Add multiple sites as you wanted
 Name        Domain pattern     Base domain name

================================================

 site 1      sandip             sandip

 site 2      gautam             gautam

 
Don't forget to make dns entries in /etc/hosts.
vi /etc/hosts
 
127.0.0.1 localhost
...
127.0.0.1 sandip
127.0.0.1 gautam
One more, by deault pages created for new sites added are not published.
Please be sure to make them published and modify contents to identify them

Now you can view different sites.
http://sandip:3000
http://gautam:3000


Thats, All
Cheers !
$@ndip
Read More…

Wednesday, August 4, 2010

Spell Check in ruby and rails using BOSSMan

by sandipransing 0 comments
Wrong English is an often problem while developing any website product as it gives bad view to website user and thus does direct impact on product. BOSSMan is a ruby gem that interacts with yahoo web service and provides a simplest way to overcome such errors.
Installation:
gem sources -a http://gems.github.com gem install jpignata-bossman Apply and get Application ID from yahoo developer network URl https://developer.apps.yahoo.com/ Make sure to note it for reference
Usage in ruby app
require 'rubygems' require 'bossman' include BOSSMan BOSSMan.application_id = "Your Application ID here"
Spelling Suggestions
text = BOSSMan::Search.spelling("gooogle") => #{"resultset_spell"=>[{"suggestion"=>"google"}], "responsecode"=>"200", "deephits"=>"1", "start"=>"0", "count"=>"1", "totalhits"=>"1"}}> text.suggestion => "google"
More sophisticated way of use -
1. Create a YML file containing list of kewords
2. Load YML file
3. Iterate YML hash to find out spell suggestions
Example: spelling.yml
1 keywords: 2 gooogle: 3 Barack Oabama: 4 Indian: 5 Latuur:
keywords = YAML.load_file('spelling.yml')['keywords'].keys puts "Correction suggested" keywords.each do |keyword| text = BOSSMan::Search.spelling(keyword) if defined? text.suggestion puts "#{keyword} => #{text.suggestion}" end end
Output
Correction suggested gooogle => google Barack Oabama => Barack Obama Latuur => Latour
Analyze suggestions manually and make neccesary corrections..
Read More…

Monday, August 2, 2010

Rails 3 Beautiful Code

by sandipransing 0 comments
Check out this SlideShare Presentation:
Read More…

Sunday, August 1, 2010

PDF in rails using prawn library

by sandipransing 0 comments
Building PDF Document in ruby & rails application using prawn Library
Brief
Before getting started with this tutorial, I would like to thanks Greg and
Prawn team
for their awesome work towards ruby and rails community.
Installing prawn (core, layout, format, security)
gem install prawn or
Add following line in rails environment file inside initializer block. config.gem 'prawn' Optionally you can specify version to be used and then run task rake gems:install Generating pdf using rails console ./script/console pdf = Prawn::Document.new It creates new pdf document object. Here you can additionally pass options parameters such as - Prawn::Document.new(:page_size => [11.32, 8.49], :page_layout => :portrait) Prawn::Document.new(A0) Here A0 is page size. Prawn::Document.new(:page_layout => :portrait, :left_margin => 10.mm, # different :right_margin => 1.cm, # units :top_margin => 0.1.dm, # work :bottom_margin => 0.01.m, # well :page_size => 'A4') pdf.text("Prawn Rocks") => 12 pdf.render_file('prawn.pdf') => # Here is output file generated [click]
Now let's go through other goodness of prawn. pdf = Prawn::Document.new('A3') do
  1. FONTS [click]
  2. # Specify font to be used or specify path to font file. font "times.ttf" font("/times.ttf")
  3. TEXT [click]
  4. text 'Sandip Ransing', :size => 41, :position => :center, :style => :bold
  5. STROKE LINE [click]
  6. stroke do rectangle [300,300], 100, 200 end
  7. IMAGE [click]
  8. Display Local file system Image image 'sandip.png', :height => 50, :position => :center, :border => 2 Scale Image image 'sandip.png', :scale => 0.5, :position => :left Display Remote image from Internet inside pdf require "open-uri" image open('http://t2.gstatic.com/images?q=tbn:kTG6gAKrnou2gM:http://www.facebook.com/profile/pic.php?uid=AAAAAQAQrLXvTWfyY2ANjttV8D1c0QAAAAnDHPFJe0pPFR84iIzXPKro&t=1") end
  9. LINE BREAKS
  10. movedown(20)
  11. TABLE/GRID [click]
  12. data = [ ["Name", {:text => 'Sandip Ransing', :font_style => :bold, :colspan => 4 }], ["Address", {:text => 'SHIVAJINAGAR, PUNE 411005', :colspan => 4 }], ["Landmark",{:text => 'NEAR FC COLLEGE', :colspan => 4 }], ["Mobile","9860648108", {:text => "", :colspan => 3 }], ["Education", {:text => "Bachelor in Computer Engineering", :colspan => 4 }], ["Vehicle", 'Hero Honda',"Reg. No.", {:text => "MH 12 EN 921", :colspan => 3 }], ["Additional", "GDCA", "class", 'First', ""], [{:text => "Areas of Speciality", :font_style => :bold}, {:text => "Ruby, Rails, Radiant, Asterisk, Adhearsion, Geokit, Prawn, ....,...", :font_style => :bold, :colspan => 4}], [{:text => "Website", :colspan => 2},{:text => "www.funonrails.com", :colspan => 3}], [{:text => "Company", :colspan => 2},{:text => "Josh Software", :colspan => 3}] ] table data, :border_style => :grid, #:underline_header :font_size => 10, :horizontal_padding => 6, :vertical_padding => 3, :border_width => 0.7, :column_widths => { 0 => 130, 1 => 100, 2 => 100, 3 => 100, 4 => 80 }, :position => :left, :align => { 0 => :left, 1 => :right, 2 => :left, 3 => :right, 4 => :right }
  13. LINKS [click]
  14. link_annotation([200, 200, 500, 40],:Border => [0,0,1], :A => { :Type => :Action, :S => :URI, :URI => Prawn::LiteralString.new("http://twitter.com/sandipransing") } ) link_annotation(([0, 100, 100, 150]), :Border => [0,0,1], :Dest => s"http://funonrails.com")
  15. PDF Security [click]
  16. encrypt_document :user_password => 'hello', :owner_password => 'railer', :permissions => { :print_document => false }
  17. Prawn Inline Formatting
  18. Prawn-format supports inline text formatting that gives user enough flexibility to use html tags. require 'prawn/format' text 'This is Strong text', :inline_format => true text 'This is bold text \n It should be on newline.', :inline_format => true
SAVE PDF File end pdf.render_file 'my.pdf' !!! NOTE: As of time now 'prawn-format' is incompatible with latest prawn gem, It is compatible with prawn version <= 0.6 s
Read More…

Friday, May 7, 2010

Specify rails version to new rails app

by sandipransing 2 comments
On my development machine, I have rails versions installed ranging from rails 1.2.3 to 2.3
How do i create new rails app that will use rails 2.1.0.
Create new app with rails version 2.1.0
  rails _2.1.0_ simple_blog

Specify database to use while creating new rails app
  rails _2.1.0_ simple_blog -d mysql
Read More…

Wednesday, April 28, 2010

using modules and mixins in ruby

by sandipransing 0 comments
Before getting started with modules and mixins, lets first find out the need of module & mixins in OOP.

In object oriented programming languages multiple inheritance is basic paradigm (child class extends behavior of base class).

C++ supports multiple inheritance. Java does support same using interfaces.
In ruby language, multiple inheritance is achieved very easily using mixin of modules & classes and that makes ruby as powerful language.

Ruby has classes, modules. Modules can be included inside other classes (mixins) to achieve multiple inheritance.

Modules module Greeting # here below is the instance method # and that can be accessed using object of class ONLY def hi puts 'Guest' end end Module methods can be called using scope resolution operator (::) or dot operator (.)
Greeting::hi # => undefined method `hi' for Greeting:Module (NoMethodError) It is obivous to have an error because we are calling class method and that is not present inside module.

Mixins Lets include greeting module inside person class
class Person include Greeting end person = Person.new person.hi #=> "Guest" Lets see how module methods can be defined. It can be done using either self or class_name.
module Greeting # here below is the instance method # and that can be accessed using object of class ONLY def hi puts 'Guest' end # Below are module methods # this methods can be invoked # using Greeting::hi # OR Greeting.hi def self.hi puts 'hi Sandip' end # here is one more way to declare # module methods def Greeting.bye puts 'Bye Sandip!' end end Lets invoke methods
Greeting::hi #=> "hi Sandip" Greeting.bye #=> "Bye Sandip!" Extending class behavior using modules
class Person def self.included(base) base.extend Greeting end end Got easy ?? Cheers!
Read More…

Monday, April 12, 2010

using thinking sphinx search in rails app

by sandipransing 0 comments
I am using acts_as_ferret and ferret server as of now with my rails application and it just works fine for me. The ONLY problem is performance as it takes a lot time to build index and to rebuild index when it gets screwed up and that's where sphinx rocks!
To get started with thinking sphinx you need to install sphinx server first. for installation help click here.
To use sphinx search in rails we need to use either thinking sphinx gem or plugin that can be easily find on github.
Plugin installation
./script/plugin install git://github.com/freelancing-god/thinking-sphinx.git
OR
To install gem run the following command.
gem install thinking-sphinx --source http://rubygems.org/ If you're upgrading, you should read this: http://freelancing-god.github.com/ts/en/upgrading.html Successfully installed thinking-sphinx-1.3.16 1 gem installed Edit environment file and add following lines to it inside initializer block.
config.gem( 'thinking-sphinx', :lib => 'thinking_sphinx', :version => '1.3.16' ) Edit Rakefile and add following lines to it. require 'thinking_sphinx/tasks' List rake task that should show up sphinx related tasks.
rake -T ts (in /home/sandip/v1) rake doc:plugins:acts_as_audited # Generate documentation for the acts_as_... rake doc:plugins:acts_as_ferret # Generate documentation for the acts_as_... rake rails:update:javascripts # Update your javascripts from your curre... rake rails:update:scripts # Add new scripts to the application scri... rake stats # Report code statistics (KLOCs, etc) fro... rake test:units # Run tests for unitsdb:test:prepare / Ru... rake tmp:sockets:clear # Clears all files in tmp/sockets rake ts:conf # Generate the Sphinx configuration file ... rake ts:config # Generate the Sphinx configuration file ... rake ts:in # Index data for Sphinx using Thinking Sp... rake ts:rebuild # Stop Sphinx (if it's running), rebuild ... rake ts:reindex # Reindex Sphinx without regenerating the... rake ts:restart # Restart Sphinx / Restart Sphinx rake ts:run # Stop if running, then start a Sphinx se... rake ts:start # Start a Sphinx searchd daemon using Thi... rake ts:stop # Stop Sphinx using Thinking Sphinx's set... rake ts:version # Output the current Thinking Sphinx vers... Start sphinx server this should give up an error.
rake ts:start (in /home/sandip/v1) Failed to start searchd daemon. Check /home/sandip/v1/log/searchd.log. Adding indexes in models
define_index do # following fields are database fields # we can not add model methods in sphinx index # sphinx fields allows ONLY model based associations # fields indexes customer_name indexes phone indexes mobile indexes other_phone indexes car_make indexes car_model indexes registration_no end Configure sphinx
rake ts:config Generating Configuration to /home/sandip/v1/config/development.sphinx.conf Index sphinx
rake ts:in (in /home/sandip/v1) Generating Configuration to /home/sandip/v1/config/development.sphinx.conf Sphinx 0.9.8-rc2 (r1234) Copyright (c) 2001-2008, Andrew Aksyonoff using config file '/home/sandip/v1/config/development.sphinx.conf'... indexing index 'call_core'... collected 113521 docs, 2.1 MB collected 0 attr values sorted 0.1 Mvalues, 100.0% done sorted 0.3 Mhits, 100.0% done total 113521 docs, 2114790 bytes total 6.102 sec, 346589.68 bytes/sec, 18604.78 docs/sec distributed index 'call' can not be directly indexed; skipping. Generating Configuration to /home/sandip/v1/config/development.sphinx.conf Sphinx 0.9.8-rc2 (r1234) Copyright (c) 2001-2008, Andrew Aksyonoff using config file '/home/sandip/v1/config/development.sphinx.conf'... indexing index 'call_core'... collected 113521 docs, 2.1 MB collected 0 attr values sorted 0.1 Mvalues, 100.0% done sorted 0.3 Mhits, 100.0% done total 113521 docs, 2114790 bytes total 3.628 sec, 582909.70 bytes/sec, 31290.34 docs/sec distributed index 'call' can not be directly indexed; skipping. Search using sphinx
./script console >>Call.search 'sandip' => [#, #]
It returns array of records found. conditions are allowed by sphinx. If you need to add conditions on integer attributes then index block in model needs to have has method like author_id in following.
define_index do indexes content indexes :name, :sortable => true indexes comments.content, :as => :comment_content indexes [author.first_name, author.last_name], :as => :author_name has author_id, created_at end
Read More…

About The Author

Sandip is a ruby on rails developer based in pune and also a blogger at funonrails. Opensource contributor and working with Josh software Private Limited. for more info read Follow Sandip on Twitter for updates.

Connect With Me...

Github Projects

@sandipransing Twitter