Pages

Thursday, 29 January 2015

Some ROR coding Standards

ROR Coding standards

Basic Stuff


 Two Spaces, No tabs

 Keep lines to a reasonable length(80 characters is classical but 100-120 is probably acceptable

with screen sizes these days)

 Method names should be intuitive and meaningful

 Variable names should be intuitive and meaningful

 Don’t commit commented out code - It makes everything confusing and it’s in the version

control anyway

 Comment when necessary - If comments are necessary check that your code couldn’t be

simplified first

 Maintain application style - If it’s a new application then be Railsy.

 If you want your application to survive then prioritize making the code easy to understand and

navigate.

Code style

 Use UTF-8. It’s 21 century, 8bit encodings dead now.

 Use 2 space indent, not tabs

 Use Unix-style line endings

 Keep lines not longer than 80 chars

 Remove trailing whitespace

Development process

 Think

 Describe

 Write tests

 Implement & go green

 Rethink

 Refactor

MVC


 Follow MVC conventions

 Do not ever mix logics: no model/view logic in controller, no view logic in model & etc.

 Follow “Fat model, skinny controllers” methodology

 If you have different data representation, use format aliases (e.g. different html views for same

data: /users/:id.iphone)

Controllers


 Keep it simple and clean

 Keep ApplicationController clean. Commonly it should be used only for global filters and per-

request logic (e.g locale configuration and access control)

 Keep in mind that all ApplicationController filters will be executed in each request and optimize

it to be ultra-fast

 Controllers should operate with abstract logic. Keep this logic simple and understandable

without detailed review. E.g:

# Disgusting


  Account.transaction do

    transfer = @sender.orders.new(:action => :transfer, :receiver => @receiver, :ammount)

   

    if @sender.assets >= amount

      @sender.assets -= amount

      @receiver.assets += amount

    else

      flash[:error] = "Balance not enough to transfer funds"

      success = false

    end

   

    if @sender.save! and @receiver.save! and transfer.save!

      flash[:info] = "You have transferred #{ammount} to #{@receiver.last_name + "" +

@receiver.first_name}"

      success = true

    else

      errors = ...

    end

  end

 

  if !success

    respond_to ...

  else

    respond_to ...

  end

# Much better, but not quite abstract


  Account.transaction do

    @sender.withdraw amount

    @receiver.deposit amount

  end

  if @sender.errors? or @receiver.errors?

    respond_to ...

  else

    respond_to ...

  end

# Best way

  if @sender.transfer!(amount, :to => @receiver)

    respond_to ...

  else

    respond_to

  end

 View interaction in controllers always should be placed in respond_to method or in responders

(for Rails 3)

 Do not place any logic in respond_to method

 Prefer :except in filters. E.g.: before_filter :authorize!, :except => [:index] to be sure that new

actions will be covered by filter by default

 Follow REST convention: Commonly one controller should only operate one resource.

 Follow REST convention naming. E.g.: UsersController should operate only users. Groups

operations should be placed in GroupsController

 Follow HTTP methods conventions in REST actions: DELETE for destructive action, PUT for

update, POST to create, GET to read

 Use nested resources when needed. E.g: map.resource :users {|user| user.resource :groups

}instead of groups action in UsersController

 Avoid deep nesting where it’s not necessary. E.g:

Not /places/:place_id/events/:event_id/usersbut /events/:event_id/users

Models


 Keep it simple and clean

 Model, method and variable names should be obvious

 Do not use shortcuts and avoid non widely used abbreviation for model names. (e.g UsrHst or

UserHist should be UserHistory)

 Don’t repeat yourself

 Don’t repeat rails. Zero custom code that duplicates rails built-in functionality

 If you use find with similar condition in more than once — use named_scope

 If you use same code in more than one model turn it into module/library

 Prefer XML Builder over to_xml overrides

Views

 Views is for presentation. DO NOT EVER CHANGE STATE OF ANYTHING IN VIEW

 Keep views simple

 Move complex logic to helpers

 Move HTML markup generation to helpers

 Do not use finders in views

 DRY. Use partials, but keep in mind that partials can be really slow

 Keep HTML markup semantic an clean

 Do not inline any Javascript code. It should be unobtrusive

Tests

 Follow Test Driven Development methodology: write tests, then code

 Keep tests simple and easy understandable

 Test everything what should be tested. If something can be broken: try to broke it by test

 Do not test rails built-in methods, test method usage


For more updates please fork on github

https://github.com/tarungarg/rails-style-guide

collection_check_boxes Rails Example

HTML code
<div style="width: 150px;height: 100px;overflow: scroll;">
 <%= check_box_tag "All" %>All<br/>   
 <%= f.collection_check_boxes  :category_ids, Category.all, :id, :category_name do |b| %>
    <span>
    <%= b.check_box(class: "check_box")%>
    <%= b.label %>
    </span>
 <% end %>
</div>
Javascript Code 
<script type="text/javascript">
  $(document).ready(function(){
    $('#All').click(function() {  
        if (this.checked) {
           $('.check_box').each(function() {
              this.checked = true;                       
           });
        } else {
           $('.checkbox').each(function() {
              this.checked = false;                       
           });
        }  
     });
   });
</script>

Google analyicts wth Rails

  1. Go to google analytics
  1. Sign Up in google analytics and fill the useful information. it will generate the javascript code. Copy that javascript code.
  2. Now paste that javascript code into the app/views/layouts/application.html.erb just up from the end of the body tag </body>.
    The given layout is the layout which I am using for all pages.

        javascript code provided by google analytics
 
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
 })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

 ga('create', 'UA-XXXX-XX', 'auto');
 ga('send', 'pageview');

  1. Most of the application are single page applications so it is necessary to keep track the ajax call also. so create a new file in app/assets/javascripts/ajax_pagetracker.js
   
Copy the below code into the file

(function ($) {
 $(document).ajaxSend(function(event, xhr, settings){
    if (typeof ga !== "undefined" && ga !== null) {
     ga('send', {
       'hitType': 'pageview',
       'page': settings.url
     });
    }
 });

})(jQuery);

Note: Keep track the ajax calls via this method is not a better option at all because it will also track the other ajax calls like (loading the assets via ajax, loading the images via ajax). So keep track the images  and other calls  is not a better option at all. so we include tracking  code manually in every ajax. For ex.

    $.ajax({
     type : 'get',
     url : url,
     data : {"curr_code": currency}
    }).done(function(){
         ga('send', {‘hitType': 'pageview', 'page':  url });
    });
   
5. Include that file into the app/assets/javascripts/application.js. If you have used                      require_tree .   
than you don’t have need to include the file.
   
//= require ajax_pagetracker

6.  In rails 4, we also use turbolinks and google analytics doesn’t track the page loaded by the     turbolinks so follow the below steps for track the pages.

Create a new file in app/assets/javascripts/turbo_pagetracker.js

Paste the below code into the file.

$(document).on('page:change', function() {
 if (typeof ga !== "undefined" && ga !== null) {
    ga('send', {
     'hitType': 'pageview',
     'page': window.location.pathname
    });
 }
});

Also Include that file into app/assets/javascripts/application.js if require_tree is not available.

7. Now watch tracking of calls on the google analytics real time overview.

Friday, 17 October 2014

Set up Chef on Ubuntu Machine

Ubuntu + Chef + Errors

On  chef server(new ubuntu machine)

cd ~
Install the chef server or install from web site
 => http://www.getchef.com/chef/install/
or
cli
=> wget https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb

Install the package using terminal
=> sudo dpkg -i chef-server*

Run this command to confugre chef server on the machine
=> sudo chef-server-ctl reconfigure

Open browser (write https and ip of server)
https://server_domain_or_IP

Add default username and password.


On workstation(diiferent ubuntu machine)

update the system
=> sudo apt-get update

Install Git
=> sudo apt-get install git

Install Curl
=> sudo apt-get install curl

You can download the chef client from wesite and manually install this.
http://www.getchef.com/chef/install/
otherwise run
=> curl -L https://www.opscode.com/chef/install.sh | sudo bash

Get the chef-repo from git
=> git clone https://github.com/opscode/chef-repo.git

create .chef repository
=> mkdir ~/chef-repo/.chef

Copy the keys:

Now we will put the keys into .chef folder so open in browser put chef server url
https://server_domain_or_IP

Login and Tap on the Clients > edit(chef-validator) > chek the checkbox > save
It will generate a key so just copy the private key and paste in

create a chef-validator file in .chef folder
=> vim chef-validator.pem
paste the key

There should be no extra space
Now same for the Users > admin > edit > check checkbox  for regenerate the private key > save
It will generate a key so just copy the private key and paste in

create a chef-validator file in .chef folder
=> vim admin.pem
paste the key

run knife command
=> knife configure --initial

PASTE THE PATH ASKED BY OPETIONS LIKE FOR admin key path should be /home/vagrant/chef-repo/.chef/admnin.pem
same for the all


No need to commit the .chef folder so
=> vim ~/chef-repo/.gitignore

Add .chef in the end of the file

.rake_test_cache

###
# Ignore Chef key files and secrets
###
.chef/*.pem
.chef/encrypted_data_bag_secret
.chef

run knife command to check if knife is configured or not
=> knife user list

if it gives error reconfigure the knife configuration

Client Node (another ubuntu instance) ip address(22.2.22.1)

now bootstrap to the clint using the following command
=> knife bootstrap 22.2.22.1 -x username -P password -N name_for_node --sudo

If bootstraps success than you will find a node in chef-repo/nodes

Now chek client list
=> knife client list


Errors faced by me

While creating node
Error: RuntimeError: Please set EDITOR environment variable
Sol:
export EDITOR=$(which vi)

ERROR: Failed to upload /home/vagrant/chef-repo/cookbooks/apt/recipes/default.rb
Sol:
Chef-server redirects api clients between its components (in this case erchef and bookshelf). These redirects are based on the FQDN of the chef-server. If the server doesn't have a valid FQDN at install time, this can result in redirects to https://localhost:443.

One solution is to fix the FQDN on chef-server and run chef-server-ctl reconfigure.

Another solution is to set a few options in /etc/chef-server/chef-server.rb (I had to create this file) and then run chef-server-ctl reconfigure.

server_name = "192.168.114.11"
api_fqdn server_name

nginx['url'] = "https://#{server_name}"
nginx['server_name'] = server_name
lb['fqdn'] = server_name
bookshelf['vip'] = server_name

Swap Memory in Ubuntu

Swap Memory + Ubuntu

I found these two blogs for swap memory which provide me a good understanding about swap memory and help me to increase swap memory of my Ubuntu system

https://www.digitalocean.com/community/tutorials/how-to-configure-virtual-memory-swap-file-on-a-vps

http://www.garron.me/en/bits/create-add-swap-file-ubuntu.html

Vagrant (Virtual Machine Manager on ubuntu)

Virtual Machine Manager + Vagrant + Generate Multiple VM's + Windows +
 Common Errors + VMware

Steps to starts

. Create a folder anywhere and give entry in the folder
   mkdir tarun

 . cd tarun

 . vagrant init   #it will generate a file named "vagrant" with cinfigurations.

 . cd vagrant

 . Add a box into the ".vagrant.d\boxes\" in C drive.

 . run command  :-
   vagrant box add precise64 "C:\Users\admin\.vagrant.d\boxes\precise64.box"

 . When you will enter into the vagrant folder you will find a vagrant configuration file. In vagrant configuration file create a global configuration for virtual box.
 
   config.vm.box = "precise64"

 . Create the three layers.
   vagrant up

 . Define 3 enviornments with same virtual box.

    config.vm.define "web" do |web|
      #web.vm.box = "web"
      #web.vm.hostname = "web"
      web.vm.network :private_network, ip: "192.168.33.10"
      web.vm.network :forwarded_port, guest: 80, host: 8080
    end

    config.vm.define "db" do |db|
      #db.vm.box = "db"
      #db.vm.hostname = "mysql"
      db.vm.network "private_network", ip: "192.168.10.22"
      db.vm.network :forwarded_port, guest: 3306, host: 8888
    end

    config.vm.define "master" do |master|
      #master.vm.box = "master"
      #master.vm.hostname = "master"
      master.vm.network "private_network", ip: "192.168.10.23"
      master.vm.network :forwarded_port, guest: 80, host: 8080
    end

  . Define networks to communicate.
    master.vm.network "private_network", ip: "192.168.10.23"

  . Define port  
    master.vm.network :forwarded_port, guest: 80, host: 8080

  . After changing run command
    vagrant reload   #helps to configure the changed configuration

  . After generate the three layers, check the virtual box.

  . To enter in the layers, use command
     vergant ssh web 


 ERRORS:

  Error: Failed to create the host-only adapter :-
  Sol:   Reinstall the virtualbox and run it as administration.
    Or update the virtual box

  Error: Vagrant cannot forward the specified ports on this VM, since they
      would collide with some other application that is already listening
      on these ports. The forwarded port to 8080 is already in use
      on the host machine.
  Sol: write    :-   , auto_correct: true
       else :- Change the host, if already defined.

Rails and Mysql Set up on ubuntu Server

Ruby + Rails + Mysql + RVM + Gemset + Apache

Steps to set up server

On Ubuntu Image

Reference Link

https://www.digitalocean.com/community/articles/how-to-install-ruby-on-rails-on-ubuntu-12-04-lts-precise-pangolin-with-rvm

1. Install curl first

sudo apt-get install curl

2. Install rvm

\curl -L https://get.rvm.io | bash -s stable

3. Path to load rvm (Given in comments after installation of )

source ~/.rvm/scripts/rvm
or
source ~/.profile

4. Requirements related to rvm

rvm requirements


5. Check version of rubies present on cloud

rvm list known

6. Install specific version

rvm install 1.9.3

7. Create gemset for particular rvm

rvm gemset create demo

8. Use gemset

rvm gemset use demo 

9. If you want to build a application from scratch than install gem rails.

gem install rails -v 3.2.14

10. Otherwise enter into the application and run

rvm use 1.9.3-p374@demo
bundle

--------------------------------------------------------------------------------------------------------------------------
Installing Mysql steps

Make sure your package management tools are up-to-date. Also make sure you install all the latest software available.

sudo apt-get update

sudo apt-get dist-upgrade

Install the MySQL server and client packages:

sudo apt-get install mysql-server mysql-client

You need to set a root password

sudo mysqladmin -u root -h localhost password 'mypassword'

sudo mysqladmin -u root -h myhostname password 'mypassword'

For Ruby dependencies install

sudo apt-get install libmysql-ruby

You can now access your MySQL server like this:

mysql -u root -p
--------------------------------------------------------------------------------------------------------------------------

Installing Apache has never been easier using apt-get.

First, I updated the repositories.

sudo apt-get update

Then fixed the locales.

sudo locale-gen en_US en_US.UTF-8 en_CA.UTF-8

sudo dpkg-reconfigure locales

And finally installed all the basic packages I thought I'd need.


sudo apt-get install apache2 curl git build-essential zlibc zlib1g-dev zlib1g libcurl4-openssl-dev libssl-dev libopenssl-ruby apache2-prefork-dev libapr1-dev libaprutil1-dev libreadline6 libreadline6-dev