preload
Jun 29

Everyone is familiar with routes in rails been a Rails developer we add and edit config/routes.rb many time throughout our application.But let get it straight how many of us actually write test for routes that we define.I guess hardly anyone does I too used to avoid writing it until I found out how easy and fun it is to write route test. So let me show you

A Routes Test has basically 3 parts

    1. assert_generate
    2. assert_recognizes
    3. assert_routing

1. assert_generate.
Asserts that the options you provide can be used to generate the provided path.
SYNTAX

assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)

Let see an example
Suppose I have a routes “http://localhost:3000/users/new” so the assert_generate for the following path look like this.

assert_generate("/users/new",:controller => "user",:action => "new")

This tell that the controller and action pair generate the provided path in this case(“/users/new”)

Now make it bit complex
What about parameters passed in to the routes,well you can write test for that as well
Here how
e.g suppose above path look like this ‘http://localhost:3000/users/new?account=1′
Now as you can see the there a additional parameter that been passed now
so the test for the above path would look like

assert_generates("/users/new",{:controller => "users" , :action => "new",:account_id => "1"}, {}, {:account_id => "1"})

Now one might ask why the path isn’t written like this ‘/users/new?account=1′ that because the ‘account_id=1′ is passed as parameters and we all know one never get a path with parameter add to routes if we do rake routes. So to take care of that extra parameter one need to tell what extra(parameter) that will be passed,in this it is “account_id”

Now when you run the following test it run without any error and failure

2. assert_recognizes.
Basically it just the inverse of assert_generate.assert_recognizes asserts that Rails recognizes the route given by expected_options.
SYNTAX

assert_recognizes(expected_options, path, extras={}, message=nil)

e.g Let do assert_recognizes for the same path(/users/new?account=1) for which we did assert_generate.
Here it is.

assert_recognizes({:controller => "users",:action => "new",:account_id => "1"},"/users/new",{:account_id => "1"})

Here again your are a specify the extra as ‘account_id’

Now see a trivial example

http://localhost:3000/users/1 => :controller => “users”, :action => “show”

http://localhost:3000/users/1 => :controller => “users”,:action => “destroy”

so the assert_recognizes for the above two would look like this

assert_recognizes({:controller => "users",:action => "show",:id => "1"},{:path => "/users/1",:method => "get"})
assert_recognizes({:controller => "users",:action => "destroy",:id => "1"},{:path => "/users/1",:method => "delete"})

3. assert_routing.
assert_routing essentially combines “assert_recognizes” and “assert_generates” into one step.
SYNTAX

assert_routing(path, options, defaults={}, extras={}, message=nil)

assert_routing for the above path are as follow

i. “http://localhost:3000/users/1?account_id=1″

assert_routing('/users/new', {:controller => 'users', :action => 'new',:account_id => "1"},{},{:account_id => "1"})

ii. “http://localhost:3000/users/1″ => Show action

assert_routing('/users/1',:controller => "users",:action => "show",:id =>"1")

iii. “http://localhost:3000/users/1″ => Destroy action with method => ‘delete’

assert_routing({:method => "delete",:path => '/users/1'}, {:controller => 'users', :action => 'destroy',:id => "1"})

You Can also try few console trick while writing the test.

$ script/console
>> routes = ActionController::Routing::Routes</strong>

>> routes.generate :controller => "users" , :action => "new"
=> "/users/new"

>> routes.generate :controller => "users" , :action => "edit", :id => "1"
=> "/users/edit/1"

>> routes.recognize_path '/users/new'
=> {:controller=>"users", :action=> "new"}

>> routes.recognize_path '/users/edit/1'
=> {:controller=> "users", :id=> "1", :action=>"edit"}
Tagged with:
May 12

In previous article we have seen that how pdf is generated  using act_as_flying_saucer plugin.

Following code snippets is used for generating pdf with bookmark .


<html>
  <head>

    <bookmarks>
      <bookmark <strong>name="Section 1" href="#section_1"</strong>>
        <bookmark name="Section 1.1" href="#section_11"></bookmark>
        <bookmark name="Section 1.2" href="#section_12"></bookmark>
      </bookmark>
      <bookmark name="Section 2" href="#section_2"></bookmark>
      <bookmark name="Section 2" href="#section_3"></bookmark>
    </bookmarks>

  </head>

  <body>

    <div style="page-break-before: always;">
      <a <strong>name="section_1"</strong>>Section 1</a>
    </div>
    <div style="page-break-before: always;">
      <a name="section_11">Section 1.1</a>
    </div>
    <div style="page-break-before: always;">
      <a name="section_12">Section 1.1.2</a>
    </div>
    <div style="page-break-before: always;">
       <a name="section_2">Section 2</a>
    </div>
    <div style="page-break-before: always;">
       <a name="section_3">Section 3</a>
    </div>

  </body>

</html>

<bookmark name=”section 1″  href=”#section_1″> tag is used to generate bookmark.
which contains name attribute for displaying name of bookmark.
href attribute is used for navigation purpose.

<bookmark> tag can be nested so it can be used for generating nested bookmark
<bookmark> tag is wrapper with <bookmarks> tag. This tag placed in html header.

Now in html body whichever anchor tag has name attribute with value as same as bookmark
href value on that position user is navigated.

Mainly two tag is used which is displayed below.

<bookmarks>
<bookmark name=”Name Of Bookmark”  href=”#bookmark1“>< /bookmark>
</bookmarks>
<a name=”bookmark1″>Text</a>

Tagged with:
May 12

Pdf with password protected in rails

In previous article we have seen that how pdf is generated  using act_as_flying_saucer plugin. Now  act_flying_saucer  has added support for  password protected pdf.

To generate PDF with password protection just pass :password=>”xxx” to render_pdf method.

render_pdf :file=>'pdf/generate_pdf.html.erb',:password=>"xxx"</pre>

You can install act_as_flying_saucer plugin

 script/plugin install git@github.com:amardaxini/acts_as_flying_saucer.git

For  further details you can visit article or visit http://github.com/amardaxini/act_as_flying_saucer

Tagged with:
May 01

In this article i have just taken a short example describing vertical table,and its implementation using rails.

When table has no fixed column it has dynamic fields .data is not stored on separate column but data stores in vertical fashion.

For implementing vertical table table has mainly 2 columns key and value pair.key is like database column name and value contains actual data.

Lets take an e.g

Consider website in which it contains various products and its comparison ,searching and many more features.product can be mobile,car etc.Product has many items.item may be nokia 6600,nokia n72 etc.

Here our aim is not compare aur search items.Here our main aim is how vertical table concept is applied.Suppose we have to build only single product comparison site then each product has it’s own attributes that can be easily build with adding column for each product.

we are developing generic site(multiple product).so there is no fixed attributes,each product has it’s own attributes either we create different model for each product or we can proceed with vertical table concept.

Vertical table

  • Product has many Product Attributes.
  • Product has many Items.
  • Item has many Item Attributes.
  • Item Attribute belongs to Product Attribute.

Product Attribute mainly requires 3 fields

name : which is used for key in vertical table(i.e column name)

option_type : which is used for viewing different form of data when item is created .(textbox,dropdown,checkbox,multi option)

option : which contain option if its drop down or multi option(serialize)

Item has only name field which is optional.

Item attribute mainly required 3 fields

name : key name or column name

value : actual value

item_id : foreign key of item

It is used where table has dynamic fields,and it only concern with data.

Here data grows vertically.

It has mainly key ,value pair.

Source code of above example is hosted on github http://github.com/amardaxini/vertical_table_demo

For More info about vertical table you can visit http://weblogs.foxite.com/andykramek/archive/2009/05/03/8369.aspx

Tagged with:
Feb 10

Static site using rails

As we know rails is mainly used for dynamic website.we can also display static web pages or we can deploy full static website using rails. The following code can help us to display static pages.

Step 1:-Create Rails project


rails static_site

Step 2:-Generate StaticPage Controller


ruby script/generate controller static_pages page

Step 3:- Create StaticPage Class in Model

 class StaticPage
   Formats = {
       "html" => "text/html",
       "png" => "image/png",
       "jpg" => "image/jpg"
     }
 end

Step 4:- Add following line in routes.rb


map.page "page/:filename.:format", :controller => 'static_pages', :action => 'page'

Here we are passing filename as parameter which is static file name.

This will generate url as http://sitename/page/static_filename.html

Step 5:- Now add following line into static_pages controller


def page
 send_file
 "#{Rails.root}/app/views/static_pages/#{params[:filename]}.#{params[:format]}",:disposition =>'inline',:type => StaticPage::Formats[params[:format]]
 end

Step 6:- All the static pages place in RAILS_ROOT/app/views/static_pages/ folder

Step 7 :- Start server and Type url as shown below.


ruby script/server

Url may be

http://railstech.com/page/contactus.html or
http://railstech.com/page/faq.html
Or In Development Mode
http://localhost:3000/page/faq.htm
http://localhost:3000/page/contactus.html

Tagged with:
Feb 05

Today, I have started testing Beta release of Rails 3.0.By Default Rails 3.0 start with webrick.To start with mongrel do following steps.

1)Install mongrel gem


sudo gem install mongrel

2) After installing mongrel gem go to config/boot.rb file

and add following line

  require "mongrel"

3) Start server as rails server

Tagged with:
Jan 19

Rails Pdf Plugin act_as_flying_saucer

There are various ways to generate pdf documents in any language.In Rails we can use prawn library ,HtmlDoc,PrinceXml and many other library,using their api we can generate pdf document.Basically the primary goal is converting HTML web pages to PDF Document,without much changing existing CSS and HTML.

Using the Flying Saucer Project we can achieve this.we can convert HTML + CSS to PDF documents without much changing HTML and CSS. It also support CSS 2 and many properties of CSS 3 for printing Header,Footer,Page Number,Paginated Tables and many more.This Project is built on Java so Java is required on system.

Lets Start How to generate PDF Using Flying Saucer.

 script/plugin install git://github.com/amardaxini/acts_as_flying_saucer.git

This Plugin forked From

http://github.com/dagi3d/acts_as_flying_saucer

Which has older version of flying saucer project.

Next Step after installing plugin add flying_saucer.rb file at config/initializers.


ActsAsFlyingSaucer::Config.options = {
:java_bin => "/usr/bin/java",          # java binary
:classpath_separator => ':',  # classpath separator. unixes system use ':' and windows ';'
:tmp_path => "/tmp",          # path where temporary files will be stored
}

After Setting Java path , classpath separator and tmp path now do following step.

class PdfController < ActionController::Base
  acts_as_flying_saucer

  def generate_pdf
    render_pdf :template => 'pdf/pdf_template'
  end
end
  render_pdf :file=>'pdf/generate_pdf.html.erb'
  render_pdf :template=>'pdf/generate_pdf.pdf.erb',
             :send_file => { :filename => 'pdfdoc.pdf' }

Add act_as_flying_saucer to controller then render_pdf.There are various ways to render pdf using “template” or “file“,:send_file option use to send pdf file to client side.if we are using any external css file then this css shoulda have media option as ‘print’.


<%= stylesheet_link_tag 'pdf' ,:media=>'print' %>

If pdf containing images which generate on the fly.so instad of using

<%= image_tag %>

use

 <img src=" " >

Before rendering PDF validate HTML,like whether all tags are close properly or not.otherwise it gives an parse error.

Now You are ready to Generate PDF. Hurray!!!!!!!!!

How to generate Header, Footer,Page Number and Automation Of HTML Validation will be discussed in next post.

Tagged with:
Sep 17

Rails Observer

Written by Amar Daxini

Observer classes respond to lifecycle callbacks to implement trigger-like behavior outside the original class. This is a great way to reduce the clutter that normally comes when the model class is burdened with functionality that doesn‘t pertain to the core responsibility of the class.


In my project,I have to track certain action (create and update) of user on particular model basically i am maintaining some kind of log, or audit trails.In my application eventlog model has attribute user and body.


class EventlogObserver < ActiveRecord::Observer
  observe :model1, :model2

  def after_create(record)
    @eventlog = Eventlog.new
    @eventlog.body = record.class.to_S+“Created at”+Time.now
    @eventlog.save
    @event
  end
  def after_update(record)
    @eventlog = Eventlog.new
    @eventlog.body = record.class.to_S+“Updated at”+Time.now
    @eventlog.save
  end
end

This eventlog_observer.rb is stored in app/model

Now Configuration add following line in /config/environment.rb config.active_record.observers = :eventlog_observer

In rails there are various callbacks on which you trigger some common behaviour

  • after_create
  • after_update
  • after_save
  • after_destroy
  • before_create
  • before_update
  • before_save
  • before_destroy

and many more you can also refer from http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

For further reference http://api.rubyonrails.org/classes/ActiveRecord/Observer.html

 
Tagged with:
Aug 19

In normal rails application contain one database,but if we want rails application having more than one database that is multiple data base.   we can achieve this using multiple way.one of the way is i am showing here.it’s just 3 steps.


Lets take an e.g Project has many milestone and milestone has many task

In normal scenario model looks like following way

 
class Project < ActiveRecord::Base 
  has_many :milestones 
end
 
class Milestone < ActiveRecord::Base 
  has_many :tasks 
 belongs_to :project 
end
 
class Task < ActiveRecord::Base 
  belongs_to :milestone 
end

Now  we want that milestone is stored on milestone_db database and task on task_db database
Rails multiple database

Now to achieve this we have to do the following steps

1) Edit Database.yml


 milestone_dev: 
 reconnect: false
 encoding: utf8 
 username: <user_name> 
 adapter: mysql 
 database: milestone_db 
 pool: 5 
 password: <password> 

task_dev: 
 reconnect: false 
 encoding: utf8 
 username: <user_name> 
 adapter: mysql 
 database: task_db 
 pool: 5 
 password: <password> 

Now create milestone_db and task_db database.


2) Edit milestone.rb and task.rb


class Milestone < ActiveRecord::Base 
  #add this line to use milestone_db 
  self.establish_connection :milestone_dev 
  has_many :tasks 
  belongs_to :project 
end 
 

class Task < ActiveRecord::Base 
  #add this line to use task_db 
  set_table_name "tasks" 
  belongs_to :milestone 
end

3) After editing model edit migration file


class CreateMilestones < ActiveRecord::Migration 
  def self.connection 
    Milestone.connection 
  end 
 .....
end

Now rails application is ready with multiple database.

Tagged with: