Wednesday, August 5, 2015

CSRF-Token Global method for all ajax request

Rails is providing many clever methods to prevent the application from the security attacks.  In that CSRF token also one of them.

Read more about CSRF.

Rails will check the CSRF token in each request, and will determine whether the token is correct or not.

If you are using any form helper to create form tag, the helper by default it will put the CSRF token in the hidden field inside the form tag.  So by submitting the form automatically the token will go with the request.  The problem comes, when we are trying to send the request through JavaScript.

To solve that, We have to add the csrf_meta_tags in layout, like below

<html>
  <head>
    <%= csrf_meta_tags %>
  </head>

  <body>
    <!-- Your body content will go here.... -->
  </body>
</html>

This will add the CSRF token in the html pages meta tag.  We can use this token in JavaScript to send AJAX request like below

beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}

This line will take the CSRF token from the meta tag and will append to the Ajax request's header.

Lets say your application is having this kind of Ajax request around 1000 places, you have to repeat this piece of code each time.  To avoid this we can write this code globally like below.

jQuery:

$(function(){

    $('#loader').hide()
    $(document).ajaxStart(function() {
        $('#loader').show();
    })
    $(document).ajaxError(function() {
        alert("Something went wrong...")
        $('#loader').hide();
    })
    $(document).ajaxStop(function() {
        $('#loader').hide();
    });
    $.ajaxSetup({
        beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}
    });
});

Coffee Script:
->
  $('#loader').hide()
  $(document).ajaxStart ->
    $('#loader').show()


  $(document).ajaxError ->
    alert("Something went wrong...")
    $('#loader').hide()


  $(document).ajaxStop ->
    $('#loader').hide()


  $.ajaxSetup {
    beforeSend: (xhr) ->
      xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
  }
Add the above script in your JavaScript file, then by default all your Ajax request will contain the CSRF token in the requests' header, and it is designed in such a way that you can show / hide loader, spinner or common error / success message for Ajax response.

Friday, February 27, 2015

Solr Start - Stop script

Solr

Solr is highly reliable, scalable and fault tolerant, providing distributed indexing, replication and load-balanced querying, automated failover and recovery, centralized configuration and more. Solr powers the search and navigation features of many of the world's largest internet sites.

Introduction


You can download the solr from here.  Setting up solr is easy as they have perfect document to do that.  Starting the solr is also easy. Go to the path, start the solr by the command what they have provided for the version you have downloaded.  By pressing Ctrl + c or by killing the port you can easily start and restart the solr.

Consider the production environment. You don't have to manually follow this process each and every time. To simplify this tedious process, follow the below steps.

Implementation



  • copy the above code and paste in /etc/init.d/solr file
  • mention your solr path, and start command in the start daemon place
  • following needs to be done in the server ( just copy paste in your terminal )
sudo update-rc.d solr defaults
sudo apt-get install chkconfig
update-rc.d solr defaults
sudo chmod og+x /etc/init.d/solr
sudo apt-get install daemon
Then you can start and stop the solr by the following command
/etc/init.d/solr start
/etc/init.d/solr stop
Thats it, now you can start and stop solr by the above command.

Friday, February 6, 2015

Dry concept for implementing JS plugins - tokeninput

Rails is always suggesting us to use DRY concept in our codes, and there are plenty of ways to achieve that.

Here I am gonna explain how we can achieve the DRY concept in adding JavaScript functionality to our Rails applications.

For explanation I have taken jQuery Tokeninput as an example.

Usually we add a plugin to our app in the following way.


Consider, the same html page is having auto complete for 3 elements.  Then you have to repeat the same code 3 times.  If the auto complete is added for many elements in the app, then you have to repeat the same code wherever it is necessary.

The same can be rewritten like below


In html.erb you can call the function like below

<% selected_countries = @user.countries.map { |c| { id: c.id, name: c.name } } %>
<%= text_field_tag("users[country_id]", {}, { :class => "auto_complete", "data-url" => "/users/get_countries", "data-duplicate" => "false", "data-selection-limit" => "10", "data-hint-text" => "Type to search  Country", "data-no-result" => "No Country found", "data-searching-text" => "Fetching Countries", "data-selected" => (selected_countries).to_json }) %>

By this way, wherever you need the autocomplete, just add the class 'auto_complete', or the class whatever you want.  Then that text field will be converted as auto complete dynamically based on the data attributes passed to the function.  So this will drastically reduce your code repetition on JavaScript side.

And you can easily call this same function on ajax success also, no need to load the JavaScript file one more time.

Above mentioned code example is for jquery tokeninput plugin, but the same behavior can be used in other plugin implementation too.

Thursday, January 29, 2015

Way to use Time and Date in Active Record Association

In Active Record associations we can write conditions also, in that case whenever you are using the association by default the condition also applied.  So it is a good practice to use condition in associations.

see the below example


The above example will return always the published comments for the user.

Problem will come, when you are using Date or Time in the condition.  Because the condition will be loaded at the time of starting your server or console.  So the date and time will be the server start time, and it won't change until you restart the server.  So you won't get expected results.

To avoid that, we should not use date and time in the association condition, we can achieve that by adding scopes with that association.

see the below example

Note: Use lambda or proc in scopes, otherwise the same problem what we trying to resolve will appear again.

Saturday, January 3, 2015

Avoid dynamic finder method for single attribute using lazy-attribute gem

Lazy Attribute

This gem provides a simple and extremely flexible way to use most frequent find_by query in a model.  You can minimize find_by query of a particular attribute in a model using lazy attribute gem.

Overview

Generally in your application, if you want to fetch a user by id, you can directly use the find method
User.find(12345)
In the same way, if you want to find any user with their username / email, they have to use any one in the below
User.find_by_email('user_email@sample.com')
User.where(email: 'user_email@sample.com').first
User.find_by(email: 'user_email@sample.com')
The lazy_attribute gem will provide way to simplify the above code.


Implementation

Add this line to your application's Gemfile:
gem 'lazy-attribute'
Add this code to your model file
class User < ActiveRecord::Base
  lazy_attribute :email
end
Then anywhere in your application you can find the user with the email attribute like below
User['user_email@sample.com']
This will return user object and will return nil in case of the user not present in the db.  And you can pass optional argument like below
lazy_attribute :email, :raise_error => true
 This will raise ActiveRecord::RecordNotFound Exception instead of sending nil on record absence case.


Source