codedecoder

breaking into the unknown…


Leave a comment

ruby plugins for netbeans

Netbeans has removed ruby support since version 7.0 . So now it do not come inbuilt with Netbeans 7.0 or 7.3 or 8.0 or any other higher version, but still available as plugin from ruby community.

You can add it with below simple steps :

=> Start your Netbeans IDE

=> Go to  Tools -> Plugins -> Settings

=> Click Add on the setting page. It will open a new window for you and provide fields to enter plugin name and URL

=> Name it ruby (you can give any name you want) . within the URL provide below.

https://blogs.oracle.com/geertjan/resource/nb-72-community-ruby.xml

=> click O.K to complete the plugin addition

=> Now click on Available Plugins tab and search for ruby or whatever name you have given to the plugin.

=> The ruby plugin will be listed in the search, click it to select and you will see install button appear at the bottom

=> just click install and follow the instruction like accept agreement, click next etc

If you do not get next button at any stage, it may be due to some missing dependency .

Earlier I was using some other URL for the plugin

http://nbruby.hron.me/updates/updates.xml

and getting below message in the installation window with the next button inactive

plugin org.netbeans.modules.web.client.tools.api is requested in version 1.0

If you face similar problem.. read this blog

=> You are done, now you can use netbeans for your Ruby development as usual…. Be Happy :)

 

REFERENCE:

http://hg.netbeans.org/community-ruby

https://blogs.oracle.com/geertjan/entry/ruby_in_netbeans_ide_7


Leave a comment

JRE not installed or Java is disabled Firefox

This error is given by browser while trying to load any java Applets , if java plugin is not installed for that browser. I will explain it in terms of firefox on ubuntu 14.04 having 64 bit architecture .

STEP 1: check the installed plugin in firefox

Type about:plugins in the firefox URL and hit enter . It will show you all the currently, installed plugin .

If you see the below detail :

IcedTea-Web Plugin (using IcedTea-Web 1.5 (1.5-1ubuntu1))

    File: IcedTeaPlugin.so
    Path: /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/IcedTeaPlugin.so
    Version:
    State: Enabled
    The IcedTea-Web Plugin executes Java applets.

It means, you already have the plugin. But if it is so, You would have not reached here :)

 

STEP 2: Install JAVA

Ubuntu support openjdk directly and can be easily installed with apt-get command as below

arun@arun-desktop:~$ sudo apt-get install openjdk-7-jdk

Now you can verify the installed java as below.

arun@arun-desktop:~$ which java
/usr/bin/java
arun@arun-desktop:~$ java -version
java version “1.7.0_55″
OpenJDK Runtime Environment (IcedTea 2.4.7) (7u55-2.4.7-1ubuntu1)
OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)

 

STEP 3: Install icedtea plugin

Firefox is default browser with ubuntu. when you install ubuntu it automatically install Firefox to /usr/lib/mozilla folder. let us inspect this folder.

arun@arun-desktop:~$ cd /usr/lib/mozilla
arun@arun-desktop:/usr/lib/mozilla$ ls
extensions  plugins
arun@arun-desktop:/usr/lib/mozilla$ cd plugins/
arun@arun-desktop:/usr/lib/mozilla/plugins$ ls
kcm_adobe_flash_player.so  librhythmbox-itms-detection-plugin.so  libtotem-gmp-plugin.so    
libtotem-narrowspace-plugin.so libtotem-cone-plugin.so libtotem-mully-plugin.so

So, there nothing seem related to java … O.K let us install it. But wait, icedtea depend on java version: Java 1.6 will require icedtea6-plugin, Java 1.7 icedtea-7-plugin. Since we have 1.7 version as seen in step 2 above we will install as below.

Also, icedta depend on openjdk, If you have sunjava jdk, it will not installed

arun@arun-desktop:~$ sudo apt-get install icedtea-7-plugin

That’s all, if you again check /usr/lib/mozilla/plugins folder you can find libjavaplugin.so added there.

Restart your firefox, your java plugin will be available now

 

REFERENCE :

http://icedtea.classpath.org/wiki/IcedTea-Web

http://tutorialforlinux.com/2013/12/08/how-to-install-oracle-java-firefox-plugin-on-linux-easy-guide/

http://stackoverflow.com/questions/11779325/installing-java-plugin-for-chrome-in-ubuntu


3 Comments

security in rails

Any thing on the net is vulnerable to attack. The threat can be at any layer: databaseweb server or web application. Some of the common security threat are : Cross Site Scripting (XSS), Cross Site Request Forgery (CSRF, XSRF), Man in the Middle (MITM)SQL Injection (SQLI)Mass Assignment & Parameter Injection etc . There is nothing like complete protection. There is a proverb in hindi “taala sarifon k liae hota hai…choron k liae nahi” , means “Lock on the door can prevent good peoples from entering the house not the thieves“. But at least the lock can make the thieve to struggle for entry and provide 60% security to our house.

Rails framework, provide 70% inbuilt security if you use all its feature properly and adhere to its security guideline . Web Security is a wide field in itself. I will keep updating this blog as I keep exploring, new security measure . Meanwhile If you want to explore it yourself, you can read the below resource :

=> Ruby on Rails Security Guide
=> Ruby official Security page
=> Rubyon Rails Security mailer list

Defence 1 : Protection against Mass Assignment attack.

Many a time, you have used @user = params[:user] in your code . This is a case of mass assignment i,e any thing coming in params[:user] will be assigned to object @user and when you save the object all of them get saved into database. Now here a attacker come, will modify the form in firefox console and add another input field for user with :admin => true , now when you do @user = params[:user] and save the object , he will get admin privilege and can do any thing now onward.

So simple to break in ..right ??

Not so easy with rails 3 and upper version. Now attributes are prevented from mass assignment by default. So you have to explicitly define the list of attributes which are eligible for mass assignment with attr_protected, or attr_accessible .

attr_accessible :name, :age # it is white listing of attributes for mass assignment

It means only name and age can be mass assigned, if params[:user] cantain any attributes say :admin => true , it will throw error.

attr_protected :admin # it is blacklisting of attributes for mass assignment

It means any attribute other then :admin can be mass assigned.

I suggest you to use attr_accessible approach. I feel it is more safe. say you add a new attribute salary in the user table but forgot to modify your model, it will automatically become eligible for mass assignment with attr_protected approach, but with attr_accessible approach it will throw error. Now if you feel salary safe to be mass assigned, you can add it to attr_accessible list.

 

Defence 2 : protection against cross site scripting (XSS) .

Oh..! You haven’t heard about cross site scripting (XSS) …Read it here . In short, It is execution of script by attacker on your page which may stole cookies session or any other information or break your application.

Let us see a simple example :

let you have a application in which person1 , input a message for person2, which get stored in db,when person2 open his account the message displayed on his page with the code <%= @message %> . But person1 is a bad Guy(remember, mom use to remind us – world is full of bad people) . He entered the message “<script>alert(‘Iam virus, Iam in..I will break your code’)</script>” .

When person2 open his page, what he will see. He will see the message “<script>alert(‘Iam virus, Iam in..I will break your code’)</script>” . No harm occur. Person1 must be cursing Rails. With Rails3 any HTML character in input will automatically escaped, in older version you have to use h() explicitly i,e the input code is <%=h text_field_tag “message” %> . More detail on escaping HTML is available here . So the ill conceived message of person1 get passed to db in harmless form as “&lt;script&gt;alert(‘Iam virus, Iam in..I will break your code’)&lt;/script&gt;” .

Now say, person1 is big crook and able to insert the message “<script>alert(‘Iam virus, Iam in..I will break your code’)</script>” in db. But person2 is again not harmed, as not only input but Rails escape any HTML in the ruby code. But what if you do not want to escape the html tag in the message. You want the message to be displayed as such, because Person3 is a nice person and he send a well decorated message “Arun <strong>I Love You</strong>” , in which I love you is highlighted . You want it to display as “Arun I Love You, rather than “Arun <strong>I Love You</strong>” . So you need to override the Rails default escaping behaviour. below will do that

<%=raw  @message %>

great, person3 message look great, but what is this person1 ill conceived message also get executed, you see the alert box below

xss example

xss example

So, person2 has succeeded in attacking your application . using raw for rendering is risky…will you use that???…I don’t think so . If you still want bolded I Love You, try other alternative than raw : sanitize .

 

 Defence 3 : Protection against CROSS SITE REQUEST FORGERY(CSRF) .

A good example of CSRF is available here . The detail documentation of preventing CSRF attack is available here . So it is more like attack through chat messages, email, images etc. This attack is mostly executed on Authenticated i,e logedIn users. Basically, the cross site scripting attack happen due to your trust on the website, which is not fulfilled while the Cross Site request forgery attack occur due to website trust on you. Website trust you with using it properly, identifying its purpose, content, flow etc. It do not expect you to click on the link like “HOT babes”, “Free tour package”, “your own FB profile link with friend request from a sweet girl” etc. If they are not part of the website on your earlier website, there is great chance that some one attempting CSRF attack.But we are INNOCENT people, we are oblivion of any such attack. Rails come to your rescue.

If you are using rails version 3 or above, you can see below within head tag of layout generated by default.

<%= csrf_meta_tags %>

This line will create a secret token for each user session. If you see the page source, you can see the below line generated by the above code.

<meta content=”sptmtpH+EZYnhrfwPplCQkATltqeHwaBAOJAgyj8CII=” name=”csrf-token” />

The above token value is stored in a hidden filed within each form. It look as below in one of my form for the current session.

<input type=”hidden” value=”sptmtpH+EZYnhrfwPplCQkATltqeHwaBAOJAgyj8CII=” name=”authenticity_token”>

When, my session expire and I log in again, this token will change. attacker can never know this secret as it is generated on fly.So attacker can disguise you to submit a form which look like a form of your web application, but he can’t bypass the authenticity token and rail will throw an error, saving us from the attack.

You can bypass the above default security measure of rails with below line of code, if you find any reason to do so.

 skip_before_filter :verify_authenticity_token

But it is like “Going to war without a shield” .will you do that…??.. NO…I know you are mature enough.

Also, always submit form with post method. Get method is too easy to attack. Post is also not fool proof, but is harder to attack.

match “/launch_all_the_missiles” => “missiles#launch_all”, :method => :get

look crazy…look like any one can destroy the world. post provide better protection against attack. If you want such route in your application write it as post method

match “/launch_all_the_missiles” => “missiles#launch_all”, :method => :post

 

Defence 4 : protection against Packet Sniffing (MITM).

Packet Sniffing is also known as Man IN The Middle attack. It is same as, you written all your secret in a letter , posted it to your lover, but postman read it before delivering. There are many software like FireShip , which  can track the bits crossing the wire, and if the data is in plain text..your game is over. Isn’t good to write the letter in encrypted word before posting, the postman would not have know the secret even if he manage to open the letter. Rails do that encryption for you if you set below configuration in your environment file.

config.force_ssl = true
It will Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. Now data will be send in encrypted form.

 

 

Defence 5: protection against SQL injection
This is one of the most common and abused attack on any web application, and involve hijacking sql command. let us take a example of a banking application, which allow a loged in user to see all the loan he has applied for. When a user click on any of the listed loan, your application show the details of that loan. Let the user is genuine one, who do not alter the params. let params[loan_id] = “23239”

Being a Rails developer, you may use where clause of Active::Record to retrieve the detail. But, you can construct a where clause in three ways as below.

1.9.3-p194 :021 > @loan = Loan.where(“loan_id = ? ” ,params[:loan_id])
Loan Load (0.1ms)  SELECT `loans`.* FROM `loans` WHERE (loan_id = ‘23239’ )
=> [#<Loan id: 376, user_id: 41, loan_number: "100150", status: "Declined", app_name: "Pisa Productions", app_date: "2014-11-24 08:00:00", relationship_manager: "", primary_borrower: nil, owner: nil, guarantor_1: nil, guarantor_2: nil, product: nil, loan_amt: 100000, business_type: nil, finance_rate: nil, payment_amt: nil, years_in_business: nil, terms: nil, created_at: "2014-01-02 11:06:08", updated_at: "2014-01-02 11:06:08", sales_force_application_id: "006d000000Gj5n5AAB", loan_id: "23239", dealership_name: "Pisa Productions">]

1.9.3-p194 :020 > @loan = Loan.where(“loan_id = ? ” ,params[:loan_id])
Loan Load (0.4ms)  SELECT `loans`.* FROM `loans` WHERE (loan_id = ‘23239’ )
=> [#<Loan id: 376, user_id: 41, loan_number: "100150", status: "Declined", app_name: "Pisa Productions", app_date: "2014-11-24 08:00:00", relationship_manager: "", primary_borrower: nil, owner: nil, guarantor_1: nil, guarantor_2: nil, product: nil, loan_amt: 100000, business_type: nil, finance_rate: nil, payment_amt: nil, years_in_business: nil, terms: nil, created_at: "2014-01-02 11:06:08", updated_at: "2014-01-02 11:06:08", sales_force_application_id: "006d000000Gj5n5AAB", loan_id: "23239", dealership_name: "Pisa Productions">]

1.9.3-p194 :022 > @loan = Loan.where(“loan_id = ‘#{params[:loan_id]}’ “)
Loan Load (0.2ms)  SELECT `loans`.* FROM `loans` WHERE (loan_id = ‘23239’ )
=> [#<Loan id: 376, user_id: 41, loan_number: "100150", status: "Declined", app_name: "Pisa Productions", app_date: "2014-11-24 08:00:00", relationship_manager: "", primary_borrower: nil, owner: nil, guarantor_1: nil, guarantor_2: nil, product: nil, loan_amt: 100000, business_type: nil, finance_rate: nil, payment_amt: nil, years_in_business: nil, terms: nil, created_at: "2014-01-02 11:06:08", updated_at: "2014-01-02 11:06:08", sales_force_application_id: "006d000000Gj5n5AAB", loan_id: "23239", dealership_name: "Pisa Productions">]

So, the sql query generated by Active::Record for the different syntax of where clause is same. But under the hood, the third form of where clause is vulnerable to sql attack but not the first two. Now say the bad guy enter, and he want to know the loan detail of any other person. He will just change the params[:loan id] to make a sql attack. This will do the trick for him.

params[:loan_id] = “‘ OR 1=1–‘”

The above is a sql injection code, you can easily see that, it will always return true as even if all other condition return false 1=1 will definitely going to return true true making the OR to return true at the end.

Again run the above in console. You will get below result.

1.9.3-p194 :024 > @loan = Loan.where(:loan_id => params[:loan_id])
Loan Load (0.3ms)  SELECT `loans`.* FROM `loans` WHERE `loans`.`loan_id` = ‘\’ OR 1=1–\”
=> []
1.9.3-p194 :025 > @loan = Loan.where(“loan_id = ? ” ,params[:loan_id])
Loan Load (0.4ms)  SELECT `loans`.* FROM `loans` WHERE (loan_id = ‘\’ OR 1=1–\” )
=> []
1.9.3-p194 :026 > @loan = Loan.where(“loan_id = ‘#{params[:loan_id]}’ “)
Loan Load (0.3ms)  SELECT `loans`.* FROM `loans` WHERE (loan_id = ” OR 1=1–” )
=>  => [#<Loan id: 376, user_id: 41, loan_number: "100150", status: "Declined", app_name: "Pisa Productions", app_date: "2014-11-24 08:00:00", relationship_manager: "", primary_borrower: nil, owner: nil, guarantor_1: nil, guarantor_2: nil, product: nil, loan_amt: 100000, business_type: nil, finance_rate: nil, payment_amt: nil, years_in_business: nil, terms: nil, created_at: "2014-01-02 11:06:08", updated_at: "2014-01-02 11:06:08", sales_force_application_id: "006d000000Gj5n5AAB", loan_id: "23239", dealership_name: "Pisa Productions">,
..all othe records]

So you can see that, the first two syntax escape the special character while generating the sql query, thus preventing from sql injection but the last one do not.

Always, be careful while writing your where clause.

Take another example, this is serious one, with your negligence any one can bypass your authentication system. You are stubborn to my advice and goes with your old way of writing the where clause.

User.where(“email = ‘#{params[:email]}’ AND encrypted_password = ‘#{params[:password]}'”)

On your login page the user just need to enter ‘ OR 1=1–‘ in both email and password field, and he will be loged in.

But Rails also not provide full protection against SQL injection, may be they get corrected in upcoming version, but currently, like where, if you not use properly all the following methods are vulnerable to sql injection( READ THE DETAIL HERE) : average ,calculate ,count , maximum ,minimum , sum, delete_all, exists?, find, find_by,join, pluck etc

 

 

REFERENCE :

http://rails-sqli.org/

http://guides.rubyonrails.org/security.html

http://blog.nvisium.com/2014/09/understanding-protectfromforgery.html

 

 


Leave a comment

copy object in ruby

When ever, you pass any object to any other method for manipulation, you should pass its copy rather then the original object to prevent any risk on the original object. See the below example.

we have below classes in bank_account.rb

class BankAccount
  attr_accessor :name, :balance
  def initialize(name,balance)
    @name = name
    @balance = balance
  end
end

class Invoice
  def print_account_holder_name(account_holder)
    puts account_holder.name.upcase
    account_holder.balance = 1000000
  end
end

BankAccount is the class which hold detail of accounts. Invoice class, generate the account report. Let us demonstrate the involved risk on console

1.9.3-p194 :014 > load “/home/arun/Documents/bank_account.rb” # give path of your bank_account.rb
1.9.3-p194 :016 > a = BankAccount.new(“arun”, 10000)
=> #<BankAccount:0xc9553d8 @name=”arun”, @balance=10000>
1.9.3-p194 :017 > Invoice.new.print_account_holder_name(a)
ARUN
1.9.3-p194 :019 > a.balance
=> 1000000

So you can see that, when print_account_holder_name method of invoice class is passed object of BankAccount class, it accidently or intentionally(in our case), increased the balance from 10000  to 10000000 . This can be avoided by passing the copy of object rather then the original object.

With the above background, we now understand the need of creating copy of object before passing to any other method or doing any manipulation over it. Let us see how we can do that i,e copy a object.

In ruby, everything is a object, even the data types. consciously or unconsciously, you have many a time created copy of these objects with assignment operator while programming.

try this in console

1.9.3-p194 :020 > a = 1
=> 1
1.9.3-p194 :023 > b = a
=> 1
1.9.3-p194 :024 > b += 1
=> 2
1.9.3-p194 :025 > a
=> 1
1.9.3-p194 :026 > b
=> 2

You can see that, you created b as a copy of a, when you add 1 to b, a do not changed i,e the manipulation occurred only on the copy b . But this way of creating copy work only for plain data type integer, string , text etc.

See again the above with a array value.

1.9.3-p194 :027 > a = [1,2]
=> [1, 2]
1.9.3-p194 :028 > b = a
=> [1, 2]
1.9.3-p194 :029 > b << 3
=> [1, 2, 3]
1.9.3-p194 :030 > a
=> [1, 2, 3]

So you can see that, creating copy with assignment operator = not worked and array assigned to a also get changed when the copy b is modified. This is because the Array object is not a primary data type. The assignment operator doesn’t make a copy of the value, it simply copies the reference to the Array object. The a and b variables are now references to the same Array object, any changes in either variable will be seen in the other.

Here dup and clone come to our rescue

1.9.3-p194 :031 > a = [1,2]
=> [1, 2]
1.9.3-p194 :032 > b = a.dup # a.clone also work
=> [1, 2]
1.9.3-p194 :033 > b << 3
=> [1, 2, 3]
1.9.3-p194 :034 > a
=> [1, 2]

So now you can see that with dup or clone, the changes on the copy not alter the original object a . Good… let us check the real scenario we have created in our  bank_account.rb.

1.9.3-p194 :039 > load “/home/arun/Documents/bank_account.rb”
=> true
1.9.3-p194 :040 > a = BankAccount.new(“arun”, 10000)
=> #<BankAccount:0xc94549c @name=”arun”, @balance=10000>
1.9.3-p194 :041 > b = a.clone
=> #<BankAccount:0xc936ce4 @name=”arun”, @balance=10000>
1.9.3-p194 :042 > c = a.dup
=> #<BankAccount:0xc929fa8 @name=”arun”, @balance=10000>
1.9.3-p194 :043 > Invoice.new.print_account_holder_name(b)
ARUN
1.9.3-p194 :044 > Invoice.new.print_account_holder_name(c)
ARUN
1.9.3-p194 :046 > a.balance
=> 10000

O.K, so this time we pass the copy b(created with dup) and copy c (created with clone) to the print_account_holder_name method of invoice class, and you can see that the balance of the original object a is secure .

Great…we will now onward create a copy of sensitive object before handing over it to any other interface for manipulation. But what is this … both dup and clone seems to doing the same thing : – copying the object . Yaa… superficially they are same, but do exhibit different behaviour. the difference can be stated in a single line as below.

clone maintain internal characteristic of copied object but dup do not .

Let us see the difference in the console.

=> dup do not maintain the frozen state of the object

1.9.3-p194 :011 > a = BankAccount.new(“arun”, 10000)
=> #<BankAccount:0x9997470 @name=”arun”, @balance=10000>
1.9.3-p194 :012 > a.freeze
=> #<BankAccount:0x9997470 @name=”arun”, @balance=10000>
1.9.3-p194 :013 > a.frozen?
=> true
1.9.3-p194 :014 > b = a.dup
=> #<BankAccount:0x99a1254 @name=”arun”, @balance=10000>
1.9.3-p194 :015 > b.frozen?
=> false
1.9.3-p194 :016 > c = a.clone
=> #<BankAccount:0x99a5cf0 @name=”arun”, @balance=10000>
1.9.3-p194 :017 > c.frozen?
=> true

So, you can see that, object a is frozen, but when it id copied with dup it become unfrozen, but remain same when copied with clone.

 

=> dup do not copy the singleton method of the object .

1.9.3-p194 :018 > a = BankAccount.new(“arun”, 10000)
=> #<BankAccount:0x99b1e38 @name=”arun”, @balance=10000>
1.9.3-p194 :019 > def a.iam_singleton
1.9.3-p194 :020?>   end

1.9.3-p194 :021 > a.methods
=> [:iam_singleton, :name, :name=, :balance, :balance=,:clone, :dup, :initialize_dup, :initialize_clone...]

1.9.3-p194 :023 > b = a.dup
=> #<BankAccount:0x99c3c3c @name=”arun”, @balance=10000>
1.9.3-p194 :024 > b.methods
=> [:name, :name=, :balance, :balance=,:clone, :dup, :initialize_dup, :initialize_clone...]

1.9.3-p194 :025 > c = a.clone
=> #<BankAccount:0x99d2110 @name=”arun”, @balance=10000>
1.9.3-p194 :026 > c.methods
=> [:iam_singleton, :name, :name=, :balance, :balance=,:clone, :dup, :initialize_dup, :initialize_clone...]

so we have added iam_singleton method to the object a . It is available to the copy c created with clone but not available to copy b created with dup.

NOTE : You can’t make copy of all the object. for example fixnum can’t be copied

 1.9.3-p194 :033 > 1.dup
TypeError: can’t dup Fixnum
1.9.3-p194 :033 > 1.clone
TypeError: can’t clone Fixnum

 

NOTE : you can customize the dup and clone method by redefining initialize_dup and initialize_clone method in your class, so overriding the original behaviour. Both initialize_dup and initialize_clone call initialize_copy method internally

O.K..so we now know the difference between dup and clone. But which one we should use. Well it is upto you. Personally, I prefer dup, as I know that Iam having only the copy of the object, so I can mess with it. I do not want any limitation on the copy I’ am having . Limitation is always a pain..isn’t it…go with dup. :)

 

Reference:

http://ruby-doc.org/core-2.1.2/Object.html#method-i-dup

http://ruby-doc.org/core-2.1.2/Object.html#method-i-clone

http://m.onkey.org/ruby-i-don-t-like-3-object-freeze

 


Leave a comment

eager loading in rails

recently I got a interview call from a reputed company and come to know that, I have not so good understanding of data loading in rails. So, I tried to dig deeper into data loading. To start with – data can be loaded in two ways : lazy loading and eager loading. The first one refer to loading associated data when need arises and second one refer to loading the associated data , at the time of retrieving the parent object itself. say you have below association

class Physician < ActiveRecord::Base
  has_many :appointments
  has_many :patients, :through => :appointments
  attr_accessible :name, :specialization, :mobile_no
end
 
class Appointment < ActiveRecord::Base
  belongs_to :physician
  belongs_to :patient
  attr_accessible :reason, :physician_id, :patient_id
end
 
class Patient < ActiveRecord::Base
  has_many :appointments
  has_many :physicians, :through => :appointments
  attr_accessible :name, :mobile_no
end

The corresponding tables for them will look as below :

class CreatePhysicians < ActiveRecord::Migration
  def change
    create_table :physicians do |t|
      t.string :name
      t.string :specialization
      t.integer :mobile_no
      t.timestamps
    end
  end
end

class CreateAppointments < ActiveRecord::Migration
  def change
    create_table :appointments do |t|
      t.string :reason
      t.references :physician
      t.references :patient
      t.timestamps
    end
  end
end

class CreatePatients < ActiveRecord::Migration
  def change
    create_table :patients do |t|
      t.string :name
      t.integer :mobile_no
      t.timestamps
    end
  end
end

Let us create some seed data to experiment with. Add below in your seeds.rb file

Physician.create(:name => "Arun", :specialization => "ENT", :mobile_no => "9569806453")
Physician.create(:name => "Anand", :specialization => "MS", :mobile_no => "9569807853")

Patient.create(:name => "Raman", :mobile_no => "9569807851")
Patient.create(:name => "Kapil", :mobile_no => "9569807852")
Patient.create(:name => "Gita", :mobile_no => "9569807853")
Patient.create(:name => "Santosh", :mobile_no => "9569807854")

Appointment.create(:reason => "Ear pain", :physician_id  => 1, :patient_id => 2)
Appointment.create(:reason => "Teeth pain", :physician_id  => 1, :patient_id => 3)
Appointment.create(:reason => "Teeth pain", :physician_id  => 1, :patient_id => 4)
Appointment.create(:reason => "Surgery", :physician_id  => 2, :patient_id => 4)
Appointment.create(:reason => "Surgery", :physician_id  => 2, :patient_id => 1)

run rake db:seed to populate the above data.

Now we have the association ready along with some dummy data.But before proceeding further, try to understand, why we need eager loading. Say the hospital need to generate a report for the months, indicating the number of patients handled by a individual doctor. You may do something like this.

1.9.3-p194 :052 > @doctors = Physician.all
Physician Load (0.2ms)  SELECT `physicians`.* FROM `physicians`
=> [#<Physician id: 1, name: "Arun", specialization: "ENT", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Physician id: 2, name: "Anand", specialization: "MS", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :059 > @doctors.each do |doctor|
1.9.3-p194 :060 >     doctor.patients.each do |patient|
1.9.3-p194 :061 >       puts patient.name
1.9.3-p194 :062?>     end
1.9.3-p194 :063?>   end
Patient Load (0.2ms)  SELECT `patients`.* FROM `patients` INNER JOIN `appointments` ON `patients`.`id` = `appointments`.`patient_id` WHERE `appointments`.`physician_id` = 1
Kapil
Gita
Santosh
Patient Load (0.3ms)  SELECT `patients`.* FROM `patients` INNER JOIN `appointments` ON `patients`.`id` = `appointments`.`patient_id` WHERE `appointments`.`physician_id` = 2
Raman
Santosh

So, you can see that for 2 doctors in database, 3 queries hitting the database. the first query was to retrieve all the doctors and 2 queries to retrieve the details of there patients. So it leads to n+ 1 queries hitting database. Imagine the load on database, if there is thousands of doctors. This can be avoided by eager loading

Now we are ready to get into the detail of eager loading.The first thing to remember is that, you can do eager loading in any of the following ways

=> includes
=> preload
=> eager_load

O.K so we have too many ways to do eager loading. Let us see how they differ by trying out them on console .

1.9.3-p194 :039 > @doctors = Physician.includes(:patients)
Physician Load (0.3ms)  SELECT `physicians`.* FROM `physicians`
Appointment Load (0.2ms)  SELECT `appointments`.* FROM `appointments` WHERE `appointments`.`physician_id` IN (1, 2)
Patient Load (0.3ms)  SELECT `patients`.* FROM `patients` WHERE `patients`.`id` IN (2, 3, 4, 1)
=> [#<Physician id: 1, name: "Arun", specialization: "ENT", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Physician id: 2, name: "Anand", specialization: "MS", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :040 > @doctors.first.patients
=> [#<Patient id: 2, name: "Kapil", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Patient id: 3, name: "Gita", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Patient id: 4, name: "Santosh", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :041 > @doctors.first.appointments
=> [#<Appointment id: 1, reason: "Ear pain", physician_id: 1, patient_id: 2, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Appointment id: 2, reason: "Teeth pain", physician_id: 1, patient_id: 3, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Appointment id: 3, reason: "Teeth pain", physician_id: 1, patient_id: 4, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]

 

1.9.3-p194 :043 > @doctors = Physician.preload(:patients)
Physician Load (0.1ms)  SELECT `physicians`.* FROM `physicians`
Appointment Load (0.1ms)  SELECT `appointments`.* FROM `appointments` WHERE `appointments`.`physician_id` IN (1, 2)
Patient Load (0.1ms)  SELECT `patients`.* FROM `patients` WHERE `patients`.`id` IN (2, 3, 4, 1)
=> [#<Physician id: 1, name: "Arun", specialization: "ENT", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Physician id: 2, name: "Anand", specialization: "MS", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :044 > @doctors.first.patients
=> [#<Patient id: 2, name: "Kapil", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Patient id: 3, name: "Gita", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Patient id: 4, name: "Santosh", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :045 > @doctors.first.appointments
=> [#<Appointment id: 1, reason: "Ear pain", physician_id: 1, patient_id: 2, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Appointment id: 2, reason: "Teeth pain", physician_id: 1, patient_id: 3, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Appointment id: 3, reason: "Teeth pain", physician_id: 1, patient_id: 4, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]

 

1.9.3-p194 :046 > @doctors = Physician.eager_load(:patients)
SQL (0.4ms)  SELECT `physicians`.`id` AS t0_r0, `physicians`.`name` AS t0_r1, `physicians`.`specialization` AS t0_r2, `physicians`.`mobile_no` AS t0_r3, `physicians`.`created_at` AS t0_r4, `physicians`.`updated_at` AS t0_r5, `patients`.`id` AS t1_r0, `patients`.`name` AS t1_r1, `patients`.`mobile_no` AS t1_r2, `patients`.`created_at` AS t1_r3, `patients`.`updated_at` AS t1_r4 FROM `physicians` LEFT OUTER JOIN `appointments` ON `appointments`.`physician_id` = `physicians`.`id` LEFT OUTER JOIN `patients` ON `patients`.`id` = `appointments`.`patient_id`
=> [#<Physician id: 1, name: "Arun", specialization: "ENT", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Physician id: 2, name: "Anand", specialization: "MS", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :047 > @doctors.first.patients
=> [#<Patient id: 2, name: "Kapil", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Patient id: 3, name: "Gita", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Patient id: 4, name: "Santosh", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :048 > @doctors.first.appointments
Appointment Load (0.3ms)  SELECT `appointments`.* FROM `appointments` WHERE `appointments`.`physician_id` = 1
=> [#<Appointment id: 1, reason: "Ear pain", physician_id: 1, patient_id: 2, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Appointment id: 2, reason: "Teeth pain", physician_id: 1, patient_id: 3, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Appointment id: 3, reason: "Teeth pain", physician_id: 1, patient_id: 4, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]

strange, appointment is not loading the through relation appointments and firing a separate query for it .let us try again by including it explicitly.

1.9.3-p194 :064 > @doctors = Physician.eager_load(:patients,:appointments)
SQL (0.4ms)  SELECT `physicians`.`id` AS t0_r0, `physicians`.`name` AS t0_r1, `physicians`.`specialization` AS t0_r2, `physicians`.`mobile_no` AS t0_r3, `physicians`.`created_at` AS t0_r4, `physicians`.`updated_at` AS t0_r5, `patients`.`id` AS t1_r0, `patients`.`name` AS t1_r1, `patients`.`mobile_no` AS t1_r2, `patients`.`created_at` AS t1_r3, `patients`.`updated_at` AS t1_r4, `appointments_physicians`.`id` AS t2_r0, `appointments_physicians`.`reason` AS t2_r1, `appointments_physicians`.`physician_id` AS t2_r2, `appointments_physicians`.`patient_id` AS t2_r3, `appointments_physicians`.`created_at` AS t2_r4, `appointments_physicians`.`updated_at` AS t2_r5 FROM `physicians` LEFT OUTER JOIN `appointments` ON `appointments`.`physician_id` = `physicians`.`id` LEFT OUTER JOIN `patients` ON `patients`.`id` = `appointments`.`patient_id` LEFT OUTER JOIN `appointments` `appointments_physicians` ON `appointments_physicians`.`physician_id` = `physicians`.`id`
=> [#<Physician id: 1, name: "Arun", specialization: "ENT", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Physician id: 2, name: "Anand", specialization: "MS", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :065 > @doctors.first.patients
=> [#<Patient id: 2, name: "Kapil", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Patient id: 3, name: "Gita", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Patient id: 4, name: "Santosh", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :066 > @doctors.first.appointments
=> [#<Appointment id: 1, reason: "Ear pain", physician_id: 1, patient_id: 2, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Appointment id: 2, reason: "Teeth pain", physician_id: 1, patient_id: 3, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Appointment id: 3, reason: "Teeth pain", physician_id: 1, patient_id: 4, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]

you can see that, this time the through association appointment also get eager loaded and no separate query fired for it.

O.K….so let us stop here and analyse the above result.

=> includes and preload made 3 queries to database . eager_load made single query to database
=> the 3 queries made by includes and preload is small queries targeted to the three table physicians, appointments and patients. the single query by eager_load involve join of all the three table
=> the query executed by includes and preload is exactly same, but eager_load query differ from both
=> eager_load do not load the through association implicitly, but you have to specify it explicitly.
=> overall time taken by includes is 0.8ms,preload is 0.3ms and eager_load is o.4ms

So, it is clear that executing a set of small queries through preload is faster than, executing a big join of these queries. Also join suffer from cartesian product overload problem as join produce a number of duplicate record which though not affect the database but hit rails on its back as it have to deal with larger number of small and short lived object.

Here rails show its smartness through includes. Actually internally rails eager load data through preload(i,e set of small queries) or eager_load(i,e through join). include just delegate the eager load to preload or eager_load depending on the nature of query you are making. In simple word, If you are not sure which is more efficient for you : preload or eager_load, just use include and it will smartly decide which one is better and delegate the job to that.

Let us see it in action on console.

1.9.3-p194 :002 > @doctors = Physician.includes(:patients).where(“patients.mobile_no != ?”, “765778989”)
SQL (0.4ms)  SELECT `physicians`.`id` AS t0_r0, `physicians`.`name` AS t0_r1, `physicians`.`specialization` AS t0_r2, `physicians`.`mobile_no` AS t0_r3, `physicians`.`created_at` AS t0_r4, `physicians`.`updated_at` AS t0_r5, `patients`.`id` AS t1_r0, `patients`.`name` AS t1_r1, `patients`.`mobile_no` AS t1_r2, `patients`.`created_at` AS t1_r3, `patients`.`updated_at` AS t1_r4 FROM `physicians` LEFT OUTER JOIN `appointments` ON `appointments`.`physician_id` = `physicians`.`id` LEFT OUTER JOIN `patients` ON `patients`.`id` = `appointments`.`patient_id` WHERE (patients.mobile_no != ‘765778989’)
=> [#<Physician id: 1, name: "Arun", specialization: "ENT", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Physician id: 2, name: "Anand", specialization: "MS", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]

So, you can see that, this time includes fire a single query through join. Here rails saw that, patient to be retrieved has some condition imposed on it, so delegated the job to eager_load internally rather then preload. Note that you can’t eager load conditional data using preload. try the above query through preload.

1.9.3-p194 :003 > @doctors = Physician.preload(:patients).where(“patients.mobile_no != ?”, “765778989”)
Physician Load (0.3ms)  SELECT `physicians`.* FROM `physicians` WHERE (patients.mobile_no != ‘765778989’)
Mysql2::Error: Unknown column ‘patients.mobile_no’ in ‘where clause': SELECT `physicians`.* FROM `physicians`  WHERE (patients.mobile_no != ‘765778989’)
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column ‘patients.mobile_no’ in ‘where clause': SELECT `physicians`.* FROM `physicians`  WHERE (patients.mobile_no != ‘765778989’)

So we get the error as expected.

Now let us make some conclusion at this point
=> use includes if you want rails to decide, to load data in single join query or small set of queries
=> use eager_load if you want to make single query to db without leaving the decision to includes
=> use preload when you want to load data with set of queries

use of preload do not look convincing…right? . let us see a case, where preload can only fit the need. Say you want the physician whose patient is Raman, but at the same time you want to eager load all the patient of that physician.

The query to find doctor whose patient is raman is as below.
1.9.3-p194 :019 > @doctors=Physician.joins(:patients).where(“patients.name = ?”, “Raman”)
Physician Load (0.1ms) SELECT `physicians`.* FROM `physicians` INNER JOIN `appointments` ON `appointments`.`physician_id` = `physicians`.`id` INNER JOIN `patients` ON `patients`.`id` = `appointments`.`patient_id` WHERE (patients.name = ‘Raman’)
=> [#]

let us chain includes to the above query to eager load the patients detail

1.9.3-p194 :017 > @doctors=Physician.joins(:patients).where(“patients.name = ?”, “Raman”).includes(:patients)
SQL (0.4ms) SELECT `physicians`.`id` AS t0_r0, `physicians`.`name` AS t0_r1, `physicians`.`specialization` AS t0_r2, `physicians`.`mobile_no` AS t0_r3, `physicians`.`created_at` AS t0_r4, `physicians`.`updated_at` AS t0_r5, `patients`.`id` AS t1_r0, `patients`.`name` AS t1_r1, `patients`.`mobile_no` AS t1_r2, `patients`.`created_at` AS t1_r3, `patients`.`updated_at` AS t1_r4 FROM `physicians` INNER JOIN `appointments` ON `appointments`.`physician_id` = `physicians`.`id` INNER JOIN `patients` ON `patients`.`id` = `appointments`.`patient_id` WHERE (patients.name = ‘Raman’)
 => [#<Physician id: 2, name: "Anand", specialization: "MS", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :018 > @doctors.first.patients
=> [#<Patient id: 1, name: "Raman", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]

So you can see that here, eager loading returning the patient Raman only as includes , seeing where clause in the query delgate the job to eager_load which create a single join with the given condition, returning only the single patient raman.

Now fire the same query, using preload.

1.9.3-p194 :015 > @doctors=Physician.joins(:patients).where(“patients.name = ?”, “Raman”).preload(:patients)
Physician Load (0.2ms)  SELECT `physicians`.* FROM `physicians` INNER JOIN `appointments` ON `appointments`.`physician_id` = `physicians`.`id` INNER JOIN `patients` ON `patients`.`id` = `appointments`.`patient_id` WHERE (patients.name = ‘Raman’)
Appointment Load (0.1ms)  SELECT `appointments`.* FROM `appointments` WHERE `appointments`.`physician_id` IN (2)
Patient Load (0.1ms)  SELECT `patients`.* FROM `patients` WHERE `patients`.`id` IN (4, 1)
=> [#<Physician id: 2, name: "Anand", specialization: "MS", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]
1.9.3-p194 :016 > @doctors.first.patients
=> [#<Patient id: 4, name: "Santosh", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">, #<Patient id: 1, name: "Raman", mobile_no: 2147483647, created_at: "2014-07-21 11:51:18", updated_at: "2014-07-21 11:51:18">]

This time you got all the patients of the physician Anand.

So, we are done with our research on data loading in rails.

But wait….Rails still evolving, and it keep changing with each release. The includes has also changed in rails4. Now rails has stopped being super smart. thus it will not automatically delegate the job to eager_load on seing a where clause in the query. instead, you need to pass the reference of the table whose attributes used in the where clause.

Example :

@doctors = Physician.includes(:patients).where(“patients.mobile_no != ?”, “765778989”) # will throw error

@doctors = Physician.includes(:patients).where(“patients.mobile_no != ?”, “765778989”).references(:patients) # will work

 

Reference :
http://guides.rubyonrails.org/active_record_querying.html
http://stackoverflow.com/questions/1208636/rails-include-vs-joins


1 Comment

inactivity warning and logout timer

Almost all the secured Application support session time out due to inactivity after specific period of time say 15 minute or 30 minute. It is good to warn the user of logout due to inactivity. Say if your application support session expire on 30 minutes of inactivity. warn user at 25 minutes. If he do not click on the warning for next 5 minute but say after 6 minute, log him out.

You should note that, you have to handle the session expiry at your application level. I am from ruby on rails background and handle this with devise gem. Devise internally clear session and cookies, if the user is inactive for 30 minute. So if user come after 30 minutes and try to reload or submit the page he is taken back to the login page.

Here, we will warn the user at 25 minutes and log him out after 30 minutes.

The logic should be :

=> You need to track user doing something on your site or not. If not keep increasing the idle time.

=> If idle time reach 25 minute give him warning popup ( I used bootstrap modal for the popup)

      NOTE : don’t use alert . it will stop your timer

=> Once popup is shown, keep counting the sub-time for the logout

=> If user come after sub-time log him out

      NOTE : In my case, as I have told above session expiry is managed by devise, reloading the page is sufficient to take user back to the login page.

In case your application do not do that, clear session cookies etc using jquery (not covered in this post) and redirect him to login page.

=> whenever user show some activity : move mouse, press key or reload page, reset the timer i,e idle time to 0 value.

To create the timer we will use setInterval and clearInterval function of JavaScript . setInterval repeat the code within it after the specified time. The time is specified in milisecod i,e if you want to repeat the process after 1 seocnd, you should pass 1000 to it .

let us first create other required things.

=> create Alert PopUP.

As mentioned above alert will stop the execution of setInterval. so let us create our own popup. I have used bootstrap . The code is as below.

<div id="inactivity_warning" class="modal hide fade" data-backdrop="static" style="top:30%">
  <div class="modal-header">
    <button type="button" class="close inactivity_ok" data-dismiss="modal" aria-hidden="true">&times;</button>
  </div>
  <div class="modal-body">
    <div class="row-fluid">
      <div id="custom_alert_message" class="span12">
       You will be logged out in 5 minutes due to inactivity. Please save your credit 
       application if you have not already done so.
     </div>
   </div>
  <div class="modal-footer">
    <a href="javascript:void(0)" class="btn inactivity_ok" data-dismiss="modal" aria-hidden="true">O.K</a>
   </div>
  </div>
</div>

save these lines in you layout so that it is available through out the application.

=> set hidden flag to decide logout and timer

Below hidden field will decide whether to logout the user or not. we will change its value to inactive when time reach 30 minutes .Set the user_loged_in value to true when user is loged in, otherwise keep it false

<input id="user_activity" name="user_activity" type="hidden" value="active" />
<input id="user_loged_in" name="user_loged_in" type="hidden" value="true" />

=> jquery code for timer

    // reset main timer i,e idle time to 0 on mouse move, keypress or reload
    window.onload = reset_main_timer;
    document.onmousemove = reset_main_timer;
    document.onkeypress = reset_main_timer;
    
    // create main_timer and sub_timer variable with 0 value, we will assign them setInterval object
    var main_timer = 0;
    var sub_timer = 0;

    // this will ensure that timer will start only when user is loged in
    var user_loged_in = $("#user_loged_in").val()

   // within dilog_set_interval function we have created object of setInterval and assigned it to main_timer.
   // within this we have again created an object of setInterval and assigned it to sub_timer. for the main_timer
   // value is set to 15000000 i,e 25 minute.note that if subtimer repeat itself after 5 minute we set user_activity
   // flag to inactive
    function dialog_set_interval(){
        main_timer = setInterval(function(){
            if(user_loged_in == "true"){
                $("#inactivity_warning").modal("show");
                sub_timer = setInterval(function(){
                    $("#user_activity").val("inactive")
                },300000);
            }
        },1500000);
    }
   // maintimer is set to 0 by calling the clearInterval function. note that clearInterval function takes
   // setInterval object as argument, which it then set to 0
    function reset_main_timer(){
        clearInterval(main_timer);
        dialog_set_interval();
    }

    // logout user if user_activity flag set to inactive, when he click ok on popup. whenuser click O.K
    // on the warning the subtimer is reset to 0
    $(".inactivity_ok").click(function(){
        clearInterval(sub_timer);
        if($("#user_activity").val() == "inactive"){
            window.location = window.location // if your application not manage session expire 
                                              //automatically. clear cookies and session her
        }
    });

NOTE : value taken by setInterval is in milisecond i,e 1000 = 1 second. In the above code 25 minutes = 15000000 and 5 minute = 300000

 

Reference:

https://developer.mozilla.org/en/docs/Web/API/window.setInterval

https://developer.mozilla.org/en-US/docs/Web/API/window.clearInterval

http://codedecoder.wordpress.com/2013/02/08/rails-with-bootstrap-javascript-jquery-plugin/

 

 


1 Comment

difference between private protected public in ruby

private, protected and public control the visibility of methods in ruby class .By default methods in ruby are public except global and initialize method which are private by default. As far as variable are concerned they are private by default as variable can’t be seen by them self but through getter and setter method defined for a variable. you can define the getter and setter method yourself, which is not actually needed as it can be achieved by using :attr_accessor. the variables for which you have defined getter and setter methods behave as public. constants are effectively public , there is no way to define a constant that is inaccessible to outside use. we can say that public, private and protected apply only to methods

private, protected and public are not any keyword but actual method of object class that operate on any other class, dynamically altering the visibility of its methods . you can get the list of private, protected or public method of a class by using private_methods , protected_methods and public_methods on it.

private, protected and public take methods name as argument. If you do not pass argument all the method following them will have the same visibility until it is changed by applying the other. Let us illustrate it with examples in visibility_demo.rb files

# this global method defined outside class so private
def iam_global
  puts "Iam global"
end

class VisibilityDemo

  def initialize
    @message = "Iam the class demonstrating visibility in ruby"
  end
  # No visibility specifier given so public by default

  def pub_method
    puts "Iam public"
  end

  private
  # This method appears after the private' visibility specifier so private
  def pri_method
    puts "Iam private"
  end

  # This method is also private because the previous visibility not overridden
  # specifier has not been overridden
  def pri_method2
    puts "Iam private"
  end

  protected
  # This method appears after the protected visibility specifier so protected
  def pro_method
    puts "Iam protected"
  end

  public
  #this method overridden above protected specifier and become public
  def pub_method2
    puts "Iam public"
  end
end

The risk in above way of defining the visibility (visibility specifier without arguments) is that all following method will have same behaviour(try by changing the position of say private, keep it at top), which we not always want, so it is better to use them in argument form if the list of particular visibility is not very long. Let us redefine it in argument form and also add some other piece of code, needed to demo visibility behaviour.

def iam_global
  puts "Iam global"
end

class VisibilityDemo

  def initialize
    @message = "Iam the class demonstrating visibility in ruby"
  end

  def pub_method
    puts "#{self}"
    puts "Iam public"
  end

  def pri_method
    puts "Iam private"
  end

  def pri_method2
    puts "Iam private"
  end

  def pro_method
    puts "Iam protected"
  end

  def demo_explicit_object_calling_pro(obj)
    #call the protected method on explcit object
    obj.pro_method
  end

  def pub_method2
    puts "Iam public"
  end

  #specifying visibility specifier with argument
  private :pri_method, :pri_method2
  protected :pro_method
end

#class inheriting from VisibilityDemo class
class InheritVisibility < VisibilityDemo
  # the will call methods of parent class with self as explicit receiver
  def call_methods_with_self
    self.pub_method
    self.pro_method
    self.pri_method
  end

  # the will call methods of parent class without any receiver
  def call_methods_without_receiver
    pub_method
    pro_method
    pri_method
  end

  #overriding private method of parent class
  def pri_method2
   puts "I have overrided parent and become public"
  end

end

#class not inheriting from VisibilityDemo
class AnyClass
  def call_methods
    pub_method
    pro_method
    pri_method
  end  
end

Now let us list all the types of method on irb console
> load “/home/arun/Desktop/visibility_demo.rb” #load the visibility_demo.rb file
=> true
> @visbiility_demo = VisibilityDemo.new # create instance of VisibilityDemo class
=> #
> @visbiility_demo.public_methods # list the public methods
=> [:pub_method, :pub_method2,...]
> @visbiility_demo.protected_methods # list the protected methods
=> [:pro_method]
> @visbiility_demo.private_methods  # list the private methods
=> [:initialize, :pri_method, :pri_method2, :iam_global, ..] # see that initialize and iam_global listed under private

O.K, so we now know how to set the visibility of a method. Let us now see how the visibility specifier change the behaviour of methods in its own class and its inherited classes.

NOTE : before you proceed you must be clear on self and implicit and explicit receiver of a method . You should also know that, there is three way of calling any method : method_name , self.method_name, @object.method_name

1 => irrespective of its visibility any method can be called only in its class hierarchy

See the below output on irb :

> @any_class = AnyClass.new # create instance of any class
 => #<AnyClass:0x942b25c>
> @any_class.pub_method # call the pub method of VisibilityDemo class
NoMethodError: undefined method `pub_method’ for #<AnyClass:0x942b25c> #give error , can’t be called
> @any_class.pro_method # call the protected method of VisibilityDemo class
NoMethodError: undefined method `pro_method’ for #<AnyClass:0x942b25c> #give error , can’t be called
> @any_class.pri_method # call the private method of VisibilityDemo class
NoMethodError: undefined method `pri_method’ for #<AnyClass:0x942b25c> #give error , can’t be called
> @any_class.call_methods # call method of AnyClass calling VisibilityDemo class method implicitly
NoMethodError: undefined method `pub_method’ for #<AnyClass:0x942b25c>

2 => Public method can be called on any object in the class hierarchy as the explicit receiver, but protected and private can’t

See the below output on the irb console :

> self
=> main
> @visbility_demo = VisibilityDemo.new # creating object of  VisibilityDemo class
 => #<VisibilityDemo:0x970c214 @message=”Iam the class demonstrating visibility in ruby”>
> @visbility_demo.pub_method #call the public method
Iam public
> @visbility_demo.pro_method #call the protected method
NoMethodError: protected method `pro_method’ called for #<VisibilityDemo:0x970c214> # give error
> @visbility_demo.pri_method #call the private method
NoMethodError: private method `pri_method’ called for #<VisibilityDemo:0x970c214> # give error

NOTE : Here there is one exception for protected method, protected method can also be called on a object if its belongs to the same class as self.

In the above output , you are running the code from irb and so at this point of program self is main, but the object @visbility_demo belongs to VisibilityDemo class, since the class of self and the class of object is different, the protected method throw error. See the below output where protected method called on explicit object and worked fine.

> @visbiility_demo = VisibilityDemo.new # creating object of VisibilityDemo
 => #<VisibilityDemo:0x955e034 @message=”Iam the class demonstrating visibility in ruby”>
> obj = VisibilityDemo.new # creating another object of VisibilityDemo
 => #<VisibilityDemo:0x9531408 @message=”Iam the class demonstrating visibility in ruby”>
> @visbiility_demo.demo_explicit_object_calling_proc(obj) #for demo_explicit_object_calling_proc method self is VisibilityDemo and since object passed to it is also of same class, the protected method worked this time
Iam protected

3 => Public and Protected both can be called with self as explicit receiver but Private can’t

See the below output on the irb console

> @inherting_visibility = InheritVisibility.new # create instance of the inheriting class
 => #<InheritVisibility:0x96e068c @message=”Iam the class demonstrating visibility in ruby”>
> @inherting_visibility.call_methods_with_self # call the method calling parent class method with self
Iam public # public method called successfully with self
Iam protected # protected method called successfully with self
NoMethodError: private method `pri_method’ called for #<InheritVisibility:0x96e068c> # private method give error

4 => public protected and private all can be called implicitly i,e without any receiver

See the below output on irb console:

> @inherting_visibility = InheritVisibility.new
 => #<InheritVisibility:0x96e068c @message=”Iam the class demonstrating visibility in ruby”>
> @inherting_visibility.call_methods_without_receiver
Iam public
Iam protected
Iam private

5 => If a private method overridden in its subclass, the method exhibit visibility as defined in subclass

see the below output in irb console

> @visibility_demo = VisibilityDemo.new # create object of VisibilityDemo class
 => #<VisibilityDemo:0x9e49734 @message=”Iam the class demonstrating visibility in ruby”>
> @visibility_demo.pri_method2 # call the private method
NoMethodError: private method `pri_method2′ called for #<VisibilityDemo:0x9e49734> # error as expected
> @inherit_visibility = InheritVisibility.new # create object of subclass of VisibilityDemo class which override the method
 => #<InheritVisibility:0x9f01e4c @message=”Iam the class demonstrating visibility in ruby”>
> @inherit_visibility.pri_method2 # call the private method of parent again
I have overrided parent and become public # it worked this time as it is overridden in the subclass 

So, from the above points we can summarized the behaviour as below :

Private method can be called only implicitly (i,e without any receiver) . Protected method can be called with a explicit receiver but that should be self or if a object, the object must belong to same class as self . Public method can be called in any way in its class hierarchy .

So through above point ruby ensure that private method should never we called on a object and let ruby invoke it by its own. Remember that you can create instance of any class anywhere and if a highly secure method say which manipulate user balance, call it current_account_balance is not private, then any person can misuse it by creating the object of class and calling the method.

Here, ruby differ in private implementation in C and c++ . In C ++  “private” means “private to this class”, while in Ruby it means “private to this instance”. What this means, in C++ from code in class A, you can access any private method for any other object of type A. In Ruby, you can not: you can only access private methods for your instance of object, and not for any other object instance (of class A).

It should be also noted that, ruby prevent accidental misuse of private method, but not prevent it strictly. So if you want, you can invoke a private method on an object also with send, see the below output on console

> @visibility_demo = VisibilityDemo.new
 => #<VisibilityDemo:0x9e8c804 @message=”Iam the class demonstrating visibility in ruby”>
> @visibility_demo.pri_method # trying to call the private method on object
NoMethodError: private method `pri_method’ called for #<VisibilityDemo:0x9e8c804> #throw no method error
> @visibility_demo.send(:pri_method) # # trying to call the private method on object with send
Iam private #it worked

Since, private method can’t be called on its own object also, but there are some cases where we me need it, so there we can make the method protected. Let us take a simple example below in file say my_bank.rb

class BankRate

  def initialize(bank_name, rate)  
    @bank_name = bank_name
    @rate      = rate  
  end 

  def bank_name
     @bank_name
  end 

  def current_rate  
    @rate  
  end 

  def comparative_rate(bank)  
    if bank.current_rate > current_rate  
      "#{bank.bank_name} have higher rate then #{@bank_name}"  
    else  
      "#{bank.bank_name} have higher rate then #{@bank_name}"  
    end  
  end 

  private :current_rate  
end  

# call the comprative_rate method
@sbi = BankRate.new("sbi", 12)  # first object of BankRate class
@icici = BankRate.new("icici", 14)  # secone object of same BankRate class
puts  @sbi.comparative_rate(@icici) # calling comprative_rate method on first object and passing second as argument

So, we have a BankRate class dealing with bank rate. We want that, the current_rate should not be misused so we have made it private. This class also have a method which compare the rate of the bank with another bank . Try to load the my_bank.rb file on console

> load “/home/arun/Desktop/my_bank.rb” #load my_bank.rb file
NoMethodError: private method `current_rate’ called for #<BankRate:0x9f90d90 @bank_name=”icici”, @rate=14>

So you can see that, although the @sbi  and @icici bot are object of the same class, still they can’t invoke the private method. Now change the visibility of current_method to protected in above file i,e protected :current_rate and run it again.

> load “/home/arun/Desktop/visibility_demo.rb” #load my_bank.rb file again
icici have higher rate then sbi # it worked this time

So, this worked this time. This demonstrate when to use private and when to use protected.

Reference :

http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes

http://lylejohnson.name/blog/2003/12/09/private-methods-in-c-and-ruby/ # comparison with c, c++

Follow

Get every new post delivered to your Inbox.