Wednesday, November 30, 2011

Handle JSON or XML request and response

Hello Guys,
        Some time we required to pass the request in particular format and get response back in same format. 

1. Consider the request and response format as JSON

Request:
curl -H "Accept: application/json" -i -X GET http://DOMAIN:PORT/controller/action/parameters
eg. curl -H "Accept: application/json" -i -X GET http://127.0.0.1:3000/posts/show/1

Response:
In the show method of posts controller we have to check whether request type is JSON than return response back to JSON format.

def show
  if request.format == Mime::JSON 
     post = Post.find_by_id(params[:id])
     render :json => post.to_json, :status => 200
  end
end

Now we get response as the requested post in .json. we will parse the json by JSON::load(response)

2. Consider the request and response format as XML

Request:
curl -H "Accept: application/xml" -i -X GET http://DOMAIN:PORT/controller/action/parameters
eg. curl -H "Accept: application/xml" -i -X GET http://127.0.0.1:3000/posts/show/1

Response:
In the show method of posts controller we have to check whether request type is XML than return response back to XML format

def show
  if request.format == Mime::XML
     post = Post.find_by_id(params[:id])
     render :xml => post, :status => 200
  end
end

Now we get response as the requested post in .xml. we will parse the xml using Hpricot or any other parser.

Hope this post will help you to deal with json and xml format.

How to invoke method in ruby?

Guys,
         Do you aware about the method invocation in ruby using different ways?
 want to know? There are 3 different ways to invoke a method in ruby.

a) Using period operator
    eg. we have class called 'Car' and we need to access the method called 'car_detail'
    car = Car.new
    car.car_detail

b) Using .send method
    car = Car.new
    car.send(:car_detail)

c) Using .call method
    car = Car.new
    car.method(:car_detail).call

So, these are the three ways to invoke method in ruby.  Hope this post will help you.

Monday, November 21, 2011

Anemone - web crawler

Hello Guys,
         Anemone is a free, multi-threaded ruby web spider framework. It is useful for collecting information about websites. It's crawl sites with initial level. With Anemone you can write task to generate statistics on a site just by giving it the URL. Anemone supports the nokogiri for HTML and XML parsing.

Lets see the simple example.. so you can get the idea how it works
 
First of all we have to install the anemone gem by
gem install anemone

It will install anemone along with dependencies robots, nokogiri.

require 'anemone'

desc "crawl the website data at initial level"
task :crawl_website => :environment do
  Anemone.crawl("http://priyankapathak.wordpress.com/") do |anemone|
    anemone.on_every_page do |page|
      puts page.url
      # store the visited pages in file system or db
    end
  end
end

As an above example, that will take a domain as 'http://priyankapathak.wordpress.com', and start tracing every page. If you want to store traced pages than just write the code to store at db or file 
system. Invoke above task by rake crawl_website --trace

There are many other inbuilt methods available with anemone. like
  • after_crawl - run a block on the PageHash (a data-structure of all the crawled pages) after the crawl is finished
  • focus_crawl - use a block to select which links to follow on each page
  • on_every_page - run a block on each page as they are encountered
  • on_pages_like - given one or more RegEx patterns, run a block on every page with a matching URL
  • skip_links_like - given one or more RegEx patterns, skip the any link that matches patten
If you find this ruby web spider interesting and want more information then simply follow below links.

Sunday, November 20, 2011

Allow ajax upload

Hello Rubies,
          Do you know how to upload the file through ajax? Last time i was juggling for ajax upload. There is some patch which i have used to allow ajax upload with rails 2.3.x. Follow below instruction to implement it.

Lets, consider the scenario. Where we have content page which has file(.pdf) upload and content area portion.

new.rhtml

<%= form_remote_tag(:url => {:controller => 'contents', :action => 'create'}, :html => { :multipart => true })%>     
    <p id='error_msgs'> </p>
    <p> Content: <%= text_area 'content', 'body' %> </p>
    <p> PDF: <%= file_column_field 'content', 'pdf_path' %> </p>
     <p> <%= submit_tag('Create') %> </p>
</form>
This form allow us to create content along with pdf upload through ajax.

Now want to add some basic validation for file?

class Content < ActiveRecord::Base
   validates_file_format_of :pdf_path , :in => ["pdf"]
   file_column(:pdf_path, :root_path => "#{RAILS_ROOT}/PDFs", :fix_file_extensions => nil)
end

Above we added the validation for file which must be in .pdf format only and store in our application's PDFs directory. You have to assume that your using file column here otherwise you can use normal file_field as well.

In controller of contents we have method called 'create' which need to enhance.

class ContentsController < ApplicationController
   
  def create
     @content = Content.new(params[:content])   
     responds_to_parent do
        if @content.save     
           render :update do |page|
              flash[:notice] = "content created successfully"
              page.redirect_to contents_url
           end
        else
           render :update do |page|
             page.replace_html "error_msgs", "#{error_messages_for :content}"
           end
        end
     end 
  end

end

Here you observed something ?.. we have used the responds_to_parent instead of respond_to block.

Now you guys are wondering about method 'responds_to_parent'. correct?
rails_responds_to_parent  is the method of gem 'rails_responds_to_parent t'. Now install that via
gem install rails_responds_to_parent

For the ajax support we have to add the patch called 'remote_upload' in lib folder of rails application

lib/remote_upload.rb

module ActionView
  module Helpers
    module PrototypeHelper
      alias_method :form_remote_tag_old, :form_remote_tag
      def form_remote_tag(options = {})
         if options[:html] && options[:html][:multipart]     
           uid = "a#{Time.now.to_f.hash}"                               
          <<-STR   
            <iframe name="#{uid}" id="#{uid}" src="about:blank" style="position:absolute;left:-100px;width:0px;height:0px;border:0px"></iframe>
            <form method="post" action="#{url_for options[:url].update({:iframe_remote => true})}" enctype="multipart/form-data" target="#{uid}" #{%(onsubmit="#{options[:loading]}") if options[:loading]}>
           STR
         else
            form_remote_tag_old(options)
         end
      end                            
    end
  end
end

This code will override the prototype's form_remote_tag method and allow iframe support.

Now, we have to include below lines in config/environment.rb to allow access of remote_upload and responds_to_parent

require 'remote_upload.rb'
require 'rails_responds_to_parent'

See our work completed. Now we will freely upload the file through ajax. Find interesting?
If you have any suggestion or query then post the comment.

to get the gem source of rails_responds_to_parent

Wednesday, November 16, 2011

How to set and skip callback with rails

Rubies,
     Want to set and skip the callback dynamically? Here is the some method which we can use to get required output.

For rails 3

Active Support provides the methods call 'skip_callback'  and 'set_callback'.
Lets we see the usage of those methods.

Assume in model we have after_save callback called 'process_me'. Now we have to skip the callback during the execution of certain method and than reset back.

# skip the callback
ModelName.skip_callback(:save, :after, :process_me)

# set the callback
ModelName.set_callback(:save, :after, :process_me)

For rails 2 

Active Record provides the some built in methods to restrict callback.

model_object.send(:update_without_callbacks) - restrict callback during update method's invocation
model_object.send(:create_without_callbacks) - restrict callback during create
method's invocation
model_object.send(:create_or_update_without_callbacks) - restrict callback during create/update method's invocation

Monday, November 14, 2011

Configure FCK Editor with rails 2.3.x (undefined method 'relative_url_root')

If you are trying to install fckeditor along with rails 2.3.x and get the error like
undefined method 'relative_url_root' then simply follow the below steps.

We require to add some patch for that.

Go to the fckeditor folder of plugin. and add patch for fckeditor

app/controllers/fckeditor_controller.rb

def upload_directory_path
   Replace this line (#136)
      uploaded = request
.relative_url_root.to_s+"#{UPLOADED}/#{params[:Type]}"
   With
      uploaded = ActionController::Base
.relative_url_root.to_s+"#{UPLOADED}/#{params[:Type]}"
    "#{uploaded}#{params[:CurrentFolder]}"
  end

lib/fckeditor.rb

Replace this line (#38)
  js_path = "#{request.relative_url_root}/javascripts"
with
  js_path = "#{ActionController::Base.relative_url_root}/javascripts"

Now restart your server. It solve the above error and fckeditor now configure successfully with your application.