1)What is the difference between include and extend?
Ans:
i)Include makes the module methods are available instance of the class.
1)Not available at the class level
2)Available at the instance level
ii)extend makes module methods are available class itself.
1)Not available at the class level
2)Available at the instance level
here is a big difference between include and extend in Ruby. Let me show you some code to explain it :
Exampl1:
module Printable
def self.class_method_x
p 'class_method_x'
end
def instance_method_y
p 'instance_method_y'
end
end
—
class ExtendDocument
extend Printable
end
—
class IncludeDocument
include Printable
end
First round, on the Printable module :
Printable.class_method_x
# => "class_method_x"
—
Printable.instance_method_y
# => NoMethodError: undefined method `instance_method_y' for Printable:Module
Second round, on ExtendDocument :
ExtendDocument.class_method_x
# => NoMethodError: undefined method `class_method_x' for ExtendDocument:Class
—
ExtendDocument.instance_method_y
# => "instance_method_y"
And on an instance of ExtendDocument :
ExtendDocument.new.class_method_x
# => NoMethodError: undefined method `class_method_x' for #<ExtendDocument:0x007fe9e308ac08>
—
ExtendDocument.new.instance_method_y
# => NoMethodError: undefined method `instance_method_y' for #<ExtendDocument:0x007fe9e3080370>
Oops, nothing is working !
Last round, on IncludeDocument :
IncludeDocument.class_method_x
# => NoMethodError: undefined method `class_method_x' for IncludeDocument:Class
IncludeDocument.instance_method_y
# => NoMethodError: undefined method `instance_method_y' for IncludeDocument:Class
And on an instance of IncludeDocument :
IncludeDocument.new.class_method_x
# => NoMethodError: undefined method `class_method_x' for #<IncludeDocument:0x007fe9e3056480>
IncludeDocument.new.instance_method_y
# => "instance_method_y"
As you’ve probably noticed, Extend a module inside a class will add the instance methods defined in the module to the extended class.
The Include will add the instance methods defined in the module to the instances of the class including the module.
Example2
module ReusableModule
def module_method
puts "Module Method: Hi there!"
end
end
class ClassThatIncludes
include ReusableModule
end
class ClassThatExtends
extend ReusableModule
end
puts "Include"
ClassThatIncludes.new.module_method # "Module Method: Hi there!"
puts "Extend"
ClassThatExtends.module_method
2)How to convert the string to integer in jquery?
x = parseInt("10")
3)What are the changes in ruby2.2.0?
i)Ruby’s Garbage Collector is now able to collect Symbol type objects. This reduces memory usage of Symbols; because GC was previously unable to collect them before 2.2. Since Rails 5.0 will require Symbol GC, it will support only Ruby 2.2 or later. (See Rails 4.2 release post for details.)
Also, a reduced pause time thanks to the new Incremental Garbage Collector will be helpful for running Rails applications. Recent developments mentioned on the Rails blog suggest that Rails 5.0 will take advantage of Incremental GC as well as Symbol GC.
ii)Another feature related to memory management is an additional option for configure.in to use jemalloc Feature #9113. This feature is still experimental and currently disabled by default until we gather performance data and more use cases. When we are convinced of the benefits, this feature will be enabled by default.
4)What is the tubolinks?
Ans:Turbolinks is a gem that will be included by default in new Rails 4 applications. It’s also compatible with Rails 3 so we can use it in our current apps too. This gem can make our applications appear faster to the user by using JavaScript to replace the HTML body of new pages instead of relying on a full page load.
Load a fresh version of a page from the server:
page:before-change a Turbolinks-enabled link has been clicked (see below for more details)
page:fetch starting to fetch a new target page
page:receive the page has been fetched from the server, but not yet parsed
page:before-unload the page has been parsed and is about to be changed
page:after-remove a node (stored in event.data) has been removed from the DOM and should be cleaned up (jQuery data is cleaned up automatically)
page:change the page has been changed to the new version (and on DOMContentLoaded)
page:update is triggered alongside both page:change and jQuery's ajaxSuccess (if jQuery is available - otherwise you can manually trigger it when calling XMLHttpRequest in your own code)
page:load is fired at the end of the loading process.
5)What is the strong parameterized?
Ans: Action Controller parameters are forbidden to be used in Active Model mass assignments until they have been whitelisted. This means you'll have to make a conscious choice about which attributes to allow for mass updating and thus prevent accidentally exposing that which shouldn't be exposed.
gem 'strong_parameters'
The strong_parameters gem is an improvement over attr_accessible to securely handle mass assignment even when you have complex authorization logic. The functionality will likely be added to Rails 4
6)What are the acess speicifiers in rails?
Ans:Public,Private,Protected
i)Public - can be called from anywhere
ii)Private - The method cannot be called outside class scope. The object send message to itself
ex: the baker has bake method as public but break_eggs is private
iii)Protected - You can call an object's protected methods as long as the default object self is an instance of the same clas as the object whose method you're calling
ex: with n protected method, c1 can ask c2 to execute c2.n, because c1 e c2 are both instances of the same class
And last but not least:
Inheritance: Subclasses inherit the method-access rules of their superclass
if "class D < C", then D will exhibit the same access behaviour as instances of C
i)Public methods can be called by all objects and subclasses of the class in which they are defined in.
ii)Protected methods are only accessible to objects within the same class.
iii)Private methods are only accessible within the same instance.
i)public - can be accessed by any object (e.g. Obj.new.public_method)
ii)protected - can only be accessed from within the object itself, as well as any subclasses
iiii)private - same as protected, but the method doesn't exist in subclasses
7)What is the Habtm?
Ans:It specifies many to many relationship with another class.
This associates two classes via an intermediate join table. Unless the join table is explicitly specified as an option, it is guessed using the lexical order of the class names. So a join between Developer and Project will give the default join table name of “developers_projects” because “D” precedes “P” alphabetically.
8)How to get the second maxmimun highet age from user table?
Ans:select * from users order by salary asc limit n-l,1;
n -> Total number of rows
l-> Which maximum number is required
9)How to write the class methods?
Ans:class A
def first_method
end
end
a = A.new.first_method
10)What is the module?
Ans:A Module is a collection of methods and constants. The methods in a module may be instance methods or module methods. Instance methods appear as methods in a class when the module is included, module methods do not. Conversely, module methods may be called without creating an encapsulating object, while instance methods may not. (See Module#module_function.)
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║ ║ class ║ module ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated ║ can *not* be instantiated ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage ║ object creation ║ mixin facility. provide ║
║ ║ ║ a namespace. ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass ║ module ║ object ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ consists of ║ methods, constants, ║ methods, constants, ║
║ ║ and variables ║ and classes ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods ║ class methods, ║ module methods, ║
║ ║ instance methods ║ instance methods ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance ║ inherits behavior and can ║ No inheritance ║
║ ║ be base for inheritance ║ ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion ║ cannot be included ║ can be included in classes and ║
║ ║ ║ modules by using the include ║
║ ║ ║ command (includes all ║
║ ║ ║ instance methods as instance ║
║ ║ ║ methods in class/module) ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension ║ can not extend with ║ module can extend instance by ║
║ ║ extend command ║ using extend command (extends ║
║ ║ (only with inheritance) ║ given instance with singleton ║
║ ║ ║ methods from module) ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝
11)Jquery click and bind functions explain?
Ans: .bind() method is used for attaching an event handler directly to elements
$("p").bind("click", function(){
alert("The paragraph was clicked.");
});
12)What is the Russian Doll Caching?
Ans:The technique of nesting fragment caches to maximize cache hits is known as russian doll caching. By nesting fragment caches, it ensures that caches can be reused even when content changes. When a change occurs to the top-most fragment cache, only that cache must be expired. Every nested cache of the parent can be reused, which provides a significant performance increase. A change to the most nested fragment cache would start a chain reaction to expire all parent caches.
et's look at an example of using the russian doll caching technique. We are going to have a Team model which has many Members. When we display a team, we must also render out member names and biographies.
class Team < ActiveRecord::Base
has_many :members
end
class Member < ActiveRecord::Base
belongs_to :team, touch: true
end
Adding the :touch option to belongs_to :team on the Member model, ensures that when a member is changed, we update the Team model as well. This is essential for using russian doll caching, as you must be able to break parent caches once children are modified.
The view template matches the hierarchy of the models. The team is the parent fragment cache, while the collection of members are its children.
<!-- app/views/teams/show.html.erb -->
<% cache @team do%>
<h1>Team: <%= @team.name %></h1>
<%= render @team.members %>
<% end %>
<!-- app/views/members/_member.html.erb -->
<% cache member do %>
<div class='member'>
<%= member.name %>
<p><%= member.bio %></p>
</div>
<% end %>
If we had a team with two members, a total of of 3 fragment caches would be written:
views/members/1-20121220141922
views/members/2-20121220141922
views/teams/2-20121220141922
The key is composed of the concatenation of the view path and the model cache_key. The cache_key returns a combination of the id of a model, plus a timestamp of the last time it was updated. This combination ensures a cache will always be expired if a model is updated.
The above technique will work seamlessly until you have to modify the template of one of the fragments. Since the template is not taken into account in the fragment cache key, any changes to the template will not expire the cache. This quickly progresses in prefixing the fragment cache keys with a version , so that an expiration will be forced. A change in a nested fragment version, will result in all parent versions needing a version bump also.
<!-- app/views/teams/show.html.erb -->
<% cache ["v1", @team] do%>
<h1>Team: <%= @team.name %></h1>
<%= render @team.members %>
<% end %>
<!-- app/views/members/_member.html.erb -->
<% cache ["v1", member] do %>
<div class='member'>
<span><%= member.name %></span>
<p><%= member.bio %></p>
</div>
<% end %>
The above version prefixing results in the following fragment caches:
views/v1/members/1-20121220141922
views/v1/members/2-20121220141922
views/v1/teams/2-20121220141922
Cache Digests
If someone forgets to change the version number of a template, and all its dependents, then the entire russian doll caching technique breaks down quickly. This happens easily, as there is no visual reference of template dependencies. For example, looking at the app/views/teams/show.html.erb template, there is no indication that each member has its own fragment cache.
Rails 4 solves this problem with cache digests. A call to #cache in your views will now suffix a digest of the template and its dependencies. No longer will you need to worry about fragment cache dependencies and versioning!
Let's take a look at out last example, now using cache digests:
<!-- app/views/teams/show.html.erb -->
<% cache @team do%>
<h1>Team: <%= @team.name %></h1>
<%= render @team.members %>
<% end %>
<!-- app/views/members/_member.html.erb -->
<% cache member do %>
<div class='member'>
<span><%= member.name %></span>
<p><%= member.bio %></p>
</div>
<% end %>
This results in the following fragment caches, now suffixed with an MD5 of the template itself:
13)What is the difference between proc and lamda?
Ans:1. Proc doesn't check the parameters passed, but Lambda does
> proc1 = Proc.new { |a, b| a + 5 }
> proc1.call(2) # call with only one parameter
=> 7 # no error, unless the block uses the 2nd parameter
> lambda1 = lambda { |a, b| a + 5 }
> lambda1.call(2)
ArgumentError: wrong number of arguments (1 for 2)
Proc will throw error only if the block uses the second param.
> proc2 = Proc.new { |a, b| a + b }
> proc2.call(2) # call with only one parameter
TypeError: nil can't be coerced into Fixnum
2. Proc returns from the calling method, while Lambda doesn't
> def meth1
> Proc.new { return 'return from proc' }.call
> return 'return from method'
> end
> puts meth1
return from proc
> def meth2
> lambda { return 'return from lambda' }.call
> return 'return from method'
> end
> puts meth2
return from method
If they are not called inside a method,
> proc1 = Proc.new { return "Thank you" }
> proc1.call
LocalJumpError: unexpected return
> lambda1 = lambda { return "Thank you" }
> lambda1.call
i)Procs, short for procedures, act similar to blocks, but can be saved as variables and reused. Think of them as blocks you can call over and over again on multiple arrays.
ii)Lambdas are very similar to procs in terms of functionality. However, they have a few key differences. Lambdas check the number of arguments passed and will return an error if you try to pass the wrong number (while procs set extra variables to nil). The other difference is that lambdas can handle a return function, whereas procs will return an error.
14)What is the scope?
Ans:Scope is a class method for retrieving and querying objects.
Scopes are nothing more than SQL scope fragments. By using these fragments one can cut down on having to write long queries each time you access content.
i)default_scope -->When the model is loaded at the same time only it will load.
ii)scope --> It will load when we are calling the scope
class Article < ActiveRecord::Base
default_scope where(:published => true) --> default scope
scope :active, -> { where state: 'active' } --> Normal scope
end
15)What is the caching?
Ans:Rails having 3 types of caching
i)Page Caching --> public/college.html -> (cache page)
ii)Action Caching -> tmp/cache/4F1 -> 'F' it will generate
iii)Fragment Caching -> tmp/cache/B7C
Gemfile
i)gem 'actionpack-page_caching'
ii)gem 'actionpack-action_caching'
Rails caching is disabled by default in the development environment. Make sure you have below the parameter value below set to true in your Rails app config file.
#Inside config/environments/development.rb
config.action_controller.perform_caching = true
Rails caching is enabled in production mode by default.
Rails Page Caching
In Rails Page Caching, whenever a request is sent to the server, the Rails server would check for the cached page and if that exists it would be served. If it does not exist, Rails server generates the page & cache it. Hence the Rails app won’t have to generate it again during the next request.
Eg
Class UserController < ActionController
caches_page :profile
def profile
@user = current_user
end
end
To expire the cache when an update is made, we will have to call an expire_page helper method.
Eg
Class UserController < ActionController
caches_page :profile
def profile
@user = current_user
end
def update
expire_page :action => profile
end
end
Here it is assumed that update action is being called when the page is updated. expire_page inside the action makes sure the cached page is purged & new cached page is created during the next call to profile action.
This type of caching in Rails is lightning fast, but one main disadvantage of this is that this can’t be used for caching every page. As the requests don’t go to the Rails app, the authentication and access restrictions using before_filter won’t work if page caching is used.
The above example is probably the wrong usage of the Rails page cache. You can see that page served by ‘profile’ action has dependency on the current_user (assume it to be logged in user).
Let’s say user_1 is the first user to view the page. The page will be generated & cached with contents for user_1 . If user_2 tries to go to his profile page, he will see user_1 content on it. This is plain wrong :) .
Rails Action Caching
While Rails Page caching caches the complete page (& the request never reaches the Rails controller), Rails action caching only caches the activities happening inside the action. For e.g., if a Rails action is fetching data from database & then rendering a view, these items would be cached & directly used the next time the cache is accessed.
In Rails Action Caching, the disadvantages of Rails Page Caching won’t be a problem as all the requests will be sent to the appropriate Rails action. Hence the authentication and access restrictions using the before_filters can be applied before serving a page.
The code for Rails Action Caching is similar to Rails Page Caching
Class UserController<ActionController
before_filter :authenticate
caches_action :profile
def profile
@user = current_user
end
def update
expire_action :action => profile
end
end
Rails Fragment Caching
Rails Fragment Caching is mainly used for dynamic pages. In this type of caching, fragments of a page can be cached and expired.
Consider an example in which an article is posted to a blog and a reader wants to post a comment to it. Since the article is the same this can be cached while the comments will always be fetched from the database. In this case we can use Rails Fragment Caching for article.
P.S. – Rails Fragment Caching is best done in the Views. The code snippet below is part of Rails View unlike previous examples where code snippets are part of Rails Controllers.
<% cache("article") do %>
<%= render article %>
<% end %>
<% @article.comments.each do |comments| %>
<%= comments.user_name %>
<%= comments.user_comment %>
<% end %>
The highlighted code will cache whatever is between `cache(‘article’) do … end`. The name `article` is used to reference the fragment cache block.
The cached fragments can be expired by using expire_fragment()
Class UserController < ActionController
def profile
@user = current_user
end
def update
expire_fragment("article")
end
end
Rails SQL Caching
SQL Caching will cache any SQL results performed by the Active Records or Data mappers automatically in each action . So, the same query doesn’t hit the database again – thereby decreasing the load time.
Eg:
Class ArticleController < ActionController
def index
@artilces = Article.all
# Run the same query again
@articles = Article.all # will pull the data from the memory and not from DB
end
end
This caching scope includes only the action in which the query is executed. In the above example, executing Article.all the second time will used cached result. But outside the action, the same query will hit the database.
Rails cache explained with an example blog app
16)What are the associations?
Ans: Association is a connection between two Active Record models
i)belongs_to -->
A belongs_to association sets up a one-to-one connection with another model, such that each instance of the declaring model "belongs to" one instance of the other model
example:
class Order < ActiveRecord::Base
belongs_to :customer
end
ii)has_one -->
A has_one association also sets up a one-to-one connection with another model, but with somewhat different semantics (and consequences). This association indicates that each instance of a model contains or possesses one instance of another model. For example, if each supplier in your application has only one account, you'd declare the supplier model like this:
class Supplier < ActiveRecord::Base
has_one :account
end
iii)has_many -->
A has_many association indicates a one-to-many connection with another model. You'll often find this association on the "other side" of a belongs_to association. This association indicates that each instance of the model has zero or more instances of another model. For example, in an application containing customers and orders, the customer model could be declared like this:
class Customer < ActiveRecord::Base
has_many :orders
end
iv)has_many :through -->
A has_many :through association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model. For example, consider a medical practice where patients make appointments to see physicians. The relevant association declarations could look like this:
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, through: :appointments
end
v)has_one :through -->
A has_one :through association sets up a one-to-one connection with another model. This association indicates that the declaring model can be matched with one instance of another model by proceeding through a third model. For example, if each supplier has one account, and each account is associated with one account history, then the supplier model could look like this:
class Supplier < ActiveRecord::Base
has_one :account
has_one :account_history, through: :account
end
class Account < ActiveRecord::Base
belongs_to :supplier
has_one :account_history
end
class AccountHistory < ActiveRecord::Base
belongs_to :account
end
vi)has_and_belongs_to_many -->
A has_and_belongs_to_many association creates a direct many-to-many connection with another model, with no intervening model. For example, if your application includes assemblies and parts, with each assembly having many parts and each part appearing in many assemblies, you could declare the models this way:
class Assembly < ActiveRecord::Base
has_and_belongs_to_many :parts
end
class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
end
jointable -> assemblies_parts
17)what is the mvc?
Ans:
The MVC() framework is an age-old architecture pattern that works very well for most applications. Rails has adopted the MVC pattern in its inherent design.
Stated Simply:
a) Model — is where the data is — the database
b) Controller — is where the logic is for the application
c) View — is where the data is used to display to the user
Process of mvc -> once request come from the browser first it will go to the routes file after it will check the corresponding controller action and controller will interact to the model and model connect to the database.after retriveing the data will send to controller and controller send back the view and display the browser.
18)What are variables in rails?
Ans:i)Local variables:Local variables begin with a lowercase letter or _. The scope of a local variable ranges from class, module, def, or do to the corresponding end or from a block's opening brace to its close brace {}.
ii)class variables:Class variables are created with the prefix ‘@@’ and are shared by all objects in a class.
!/usr/bin/ruby
class Customer
@@no_of_customers=0
def initialize(id, name, addr)
@cust_id=id
@cust_name=name
@cust_addr=addr
end
def display_details()
puts "Customer id #@cust_id"
puts "Customer name #@cust_name"
puts "Customer address #@cust_addr"
end
def total_no_of_customers()
@@no_of_customers += 1
puts "Total number of customers: #@@no_of_customers"
end
end
# Create Objects
cust1=Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2=Customer.new("2", "Poul", "New Empire road, Khandala")
# Call Methods
cust1.total_no_of_customers()
cust2.total_no_of_customers()
Here @@no_of_customers is a class variable. This will produce the following result:
Total number of customers: 1
Total number of customers: 2
iii)global variables:Global variables are declared with the ‘$’ symbol and can be declared and used anywhere within your program. You should use them sparingly to never.
$global_variable = 10
class Class1
def print_global
puts "Global variable in Class1 is #$global_variable"
end
end
class Class2
def print_global
puts "Global variable in Class2 is #$global_variable"
end
end
class1obj = Class1.new
class1obj.print_global
class2obj = Class2.new
class2obj.print_global
Here $global_variable is a global variable. This will produce the following result:
NOTE: In Ruby you CAN access value of any variable or constant by putting a hash (#) character just before that variable or constant.
Global variable in Class1 is 10
Global variable in Class2 is 10
iv)instance variables:Instance variables are created with the prefix ‘@’ and belong to a single object within a class.
ex:class Customer
def initialize(id, name, addr)
@cust_id=id
@cust_name=name
@cust_addr=addr
end
def display_details()
puts "Customer id #@cust_id"
puts "Customer name #@cust_name"
puts "Customer address #@cust_addr"
end
end
# Create Objects
cust1=Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2=Customer.new("2", "Poul", "New Empire road, Khandala")
# Call Methods
cust1.display_details()
cust2.display_details()
Here, @cust_id, @cust_name and @cust_addr are instance variables. This will produce the following result:
Customer id 1
Customer name John
Customer address Wisdom Apartments, Ludhiya
Customer id 2
Customer name Poul
Customer address New Empire road, Khandala
19)How to set the tablename in rails?
Ans:
class Countries < ActiveRecord::Base
self.table_name = "cc"
end
20)What is the difference between ruby hash and parameters hash?
Ans:
21)How to call the class methods in rails?
Ans:
class Sample
def koti
p "hello koti"
end
end
a = Sample.new()
a.koti
22)What is the difference between mysql and postgresql?
Mysql
i)MySQL is a fast, easy-to-use RDBMS being used for many small and big businesses. MySQL is developed, marketed, and supported by MySQL AB, which is a Swedish company. MySQL is becoming so popular because of many good reasons:
ii)MySQL is released under an open-source license. So you have nothing to pay to use it.
iii)MySQL is a very powerful program in its own right. It handles a large subset of the functionality of the most expensive and powerful database packages.
iv)MySQL uses a standard form of the well-known SQL data language.
v)MySQL works on many operating systems and with many languages including PHP, PERL, C, C++, JAVA, etc.
v)MySQL works very quickly and works well even with large data sets.
vi)MySQL is very friendly to PHP, the most appreciated language for web development.
vii)MySQL supports large databases, up to 50 million rows or more in a table. The default file size limit for a table is 4GB, but you can increase this (if your operating system can handle it) to a theoretical limit of 8 million terabytes (TB).
viii)MySQL is customizable. The open-source GPL license allows programmers to modify the MySQL software to fit their own specific environments.
Postgresql:
i)PostgreSQL is a powerful, open source object-relational database system. It has more than 15 years of active development and a proven architecture that has earned it a strong reputation for reliability, data integrity, and correctness.
ii)Complex SQL queries
iii)SQL Sub-selects
iv)Foreign keys
v)Trigger
vi)Views
vii)Transactions
viii)Multiversion concurrency control (MVCC)
ix)Streaming Replication (as of 9.0)
x)Hot Standby (as of 9.0)
***postgres is secure, fast, n full of features but comparatively tricky to use.
23)What is the cronjob?What gem used for cronjob?
Ans:Cron is a piece of software written for *nix-type operating systems to help with the scheduling of recurring tasks. You may want to use cron to schedule certain recurring actions in your Rails application.Cron is great for handling recurring tasks
Gem Name:gem 'whenever', :require => false
wheneverize .
config/schedule.rb
example:
every 3.hours do
runner "MyModel.some_process"
rake "my:rake:task"
end
24)How to implement custom validation in rails?
Ans:When we are bulit in rails application.the validation helpers are not sufficient we can write the custom validations using
Custom validators are classes that extend ActiveModel::Validator
Example:
class Invoice < ActiveRecord::Base
validate :expiration_date_cannot_be_in_the_past,
:discount_cannot_be_greater_than_total_value
def expiration_date_cannot_be_in_the_past
if !expiration_date.blank? and expiration_date < Date.today
errors.add(:expiration_date, "can't be in the past")
end
end
def discount_cannot_be_greater_than_total_value
if discount > total_value
errors.add(:discount, "can't be greater than total value")
end
end
25)Rails resource :photos -> list out all the routes
Ans:
HTTP Verb Path Controller#Action Used for
GET /photos photos#index display a list of all photos
GET /photos/new photos#new return an HTML form for creating a new photo
POST /photos photos#create create a new photo
GET /photos/:id photos#show display a specific photo
GET /photos/:id/edit photos#edit return an HTML form for editing a photo
PATCH/PUT /photos/:id photos#update update a specific photo
DELETE /photos/:id photos#destroy delete a specific photo
26)What is the callbacks? How many callbacks are available?
Ans:Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.
Types of Callbacks:
i)before_validation
ii)after_validation
iii)before_save
iv)around_save
v)before_create
vi)around_create
vii)after_create
viii)after_save
ix)before_update
x)around_update
xi)after_update
xii)after_commit/after_rollback
27)What is the filters? How many filters are available?ns
Ans:
Rails 3-> Rails4 (changeing filters to actions)
i)Filters are methods that are run before, after or "around" a controller action.
ii)Filters are inherited, so if you set a filter on ApplicationController, it will be run on every controller in your application.
Types of Filters:
i)before_filter :get_user_name --->"Before" filters may halt the request cycle. A common "before" filter is one which requires that a user is logged in for an action to be run
class ApplicationController < ActionController::Base
before_action :require_login
private
def require_login
unless logged_in?
flash[:error] = "You must be logged in to access this section"
redirect_to new_login_url # halts request cycle
end
end
end
ii)after_filter :update_user_details ---> After" filters are similar to "before" filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, "after" filters cannot stop the action from running
iii)around_filter :update_tarnsaction --->
"Around" filters are responsible for running their associated actions by yielding, similar to how Rack middlewares work.
class ChangesController < ApplicationController
around_action :wrap_in_transaction, only: :show
private
def wrap_in_transaction
ActiveRecord::Base.transaction do
begin
yield
ensure
raise ActiveRecord::Rollback
end
end
end
end
28)What is the difference between the collection and memember in routes?
Ans:A member route will require an ID, because it acts on a member. A collection route doesn't because it acts on a collection of objects.
resources :photos do
member do
get :preview
end
end
resources :photos do
collection do
get :search
end
end
URL Helper Description
----------------------------------------------------------------------------------------------------------------------------------
member /photos/1/preview preview_photo_path(photo) Acts on a specific resource so required id (preview specific photo)
collection /photos/search search_photos_url Acts on collection of resources(display all photos)
29)What is the nested resoures?
Ans:Ruby on Rails allows you to set up nested resources. For instance in the "Getting started" guide where you build a very simple blog, Post and Comment are nested resources. Indeed, it is impossible to consider a lone comment without any post. A Comment belongs to a Post. Resources being referenced by URIs, the setup of nested resources in RoR is done through routing as following:
resources :posts do
resources :comments
end
30)What is the use of concerns in rails4?
Ans: Main use of concerns are implement the modules.The Rails Concern are used to DRYING the code for both models and controllers.So just by including the module,either in model/controller you get the methods and you can call them just like you call it usually as if they are defined within the controller/model.
1) DRYing up model codes
Consider a Article model, a Event model and a Comment model. An article or an event has many comments. A comment belongs to either Article or Event.
Traditionally, the models may look like this:
Comment Model:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
Article Model:
class Article < ActiveRecord::Base
has_many :comments, as: :commentable
def find_first_comment
comments.first(created_at DESC)
end
def self.least_commented
#return the article with least number of comments
end
end
Event Model
class Event < ActiveRecord::Base
has_many :comments, as: :commentable
def find_first_comment
comments.first(created_at DESC)
end
def self.least_commented
#returns the event with least number of comments
end
end
As we can notice, there is a significant piece of code common to both Event and Article. Using concerns we can extract this common code in a separate module Commentable.
For this create a commentable.rb file in app/model/concerns.
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments, as: :commentable
end
# for the given article/event returns the first comment
def find_first_comment
comments.first(created_at DESC)
end
module ClassMethods
def least_commented
#returns the article/event which has the least number of comments
end
end
end
And Now your models look like this :
Comment Model:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
Article Model:
class Article < ActiveRecord::Base
include Commentable
end
Event Model:
class Event < ActiveRecord::Base
include Commentable
end
2) Skin-nizing Fat Models.
Consider a Event model. A event has many attenders and comments.
Typically, the event model might look like this
class Event < ActiveRecord::Base
has_many :comments
has_many :attenders
def find_first_comment
# for the given article/event returns the first comment
end
def find_comments_with_word(word)
# for the given event returns an array of comments which contain the given word
end
def self.least_commented
# finds the event which has the least number of comments
end
def self.most_attended
# returns the event with most number of attendes
end
def has_attendee(attendee_id)
# returns true if the event has the mentioned attendee
end
end
Models with many associations and otherwise have tendency to accumulate more and more code and become unmanageable.Concerns provide a way to skin-nize fat modules making them more modularized and easy to understand.
The above model can be refactored using concerns as below: Create a attendable.rd and commentable.rb file in app/model/concern/event folder
attendable.rb
module Attendable
extend ActiveSupport::Concern
included do
has_many :attenders
end
def has_attender(attender_id)
# returns true if the event has the mentioned attendee
end
module ClassMethods
def most_attended
# returns the event with most number of attendes
end
end
end
commentable.rb
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments
end
def find_first_comment
# for the given article/event returns the first comment
end
def find_comments_with_word(word)
# for the given event returns an array of comments which contain the given word
end
module ClassMethods
def least_commented
# finds the event which has the least number of comments
end
end
end
And now using Concerns , your Event model reduces to
class Event < ActiveRecord::Base
include Commentable
include Attendable
end
* While using concerns its advisable to go for 'domain' based grouping rather than 'technical' grouping. Domain Based grouping is like 'Commentable', 'Photoable', 'Attendable'. Technical grouping will mean 'ValidationMethods', 'FinderMethods' etc
31)What are the selectors in jquery?
Ans:i)class,ii)id
32)What is the difference between has_and_belongs_to_many and has_many through?
Ans:has_and_belongs_to_many doenot require model.where has_many through require the model.
33)What is the capistrano?How to deploy the using capistrano in rails?
Ans:Capisrano is a ruby gem.deploying the code from developer to desktop to server
34)What is the bdd and tdd?
Ans:BDD ---> Behaviour Driven Development ---> Cucumber
TDD ----> Test Driven Development ---> Rspec --->TDD is all about writing tests first. This basically forces you to write your own client before you write your application code. The cycle is generally write a test for an API that doesn't exist, run the test expecting it to fail, go write your API code, run your test again and make sure it passes. Then write your next test... and so on
i). BDD focuses on specifying what will happen next. where as TDD focuses on setting up a set of conditions and then looking at the output.
ii). BDD specifies behaviours while TDD specifies outcomes.
iii). BDD can be layered, while outcomes(TDD) cannot.
iv). TDD is for testing and we can’t perform Design process, Requirements capturing and Behavior specification in TDD, but these can be possible in BDD.
v). BDD is mainly used as a communication tool. its main goal is write executable specifications which can be understood by the domain experts.
vi). the main difference between BDD and TDD is wording. as these are important for communicating your intend.
BDD
Given the user is logged in
*** test code***
And they are an administrator
***test code***
When the deleteUser is called
***test code***
Then the user will be removed from the system
***test code***
And they will also be removed from any groups they belong to
***test code***
TDD (done badly)
Test SomeClass delete method()
***test code***
The top one can be read and understood by a domain expert, the bottom one the reader would have to guess the intended behaviour by reading the test code.
The advantage of BDD is that the same semantics can also be used for user stories and acceptance criteria. Therefore acting as a bridge between specification and code.
35)Difference between class and module?
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║ ║ class ║ module ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated ║ can *not* be instantiated ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage ║ object creation ║ mixin facility. provide ║
║ ║ ║ a namespace. ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass ║ module ║ object ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ consists of ║ methods, constants, ║ methods, constants, ║
║ ║ and variables ║ and classes ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods ║ class methods, ║ module methods, ║
║ ║ instance methods ║ instance methods ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance ║ inherits behavior and can ║ No inheritance ║
║ ║ be base for inheritance ║ ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion ║ cannot be included ║ can be included in classes and ║
║ ║ ║ modules by using the include ║
║ ║ ║ command (includes all ║
║ ║ ║ instance methods as instance ║
║ ║ ║ methods in class/module) ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension ║ can not extend with ║ module can extend instance by ║
║ ║ extend command ║ using extend command (extends ║
║ ║ (only with inheritance) ║ given instance with singleton ║
║ ║ ║ methods from module) ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝
36)What is the activerecord?
Ans:ActiveRecord provides an object-oriented interface to an application's database to make development easier and friendlier for the developer. It provides validation functionality as well which helps keep data in the database clean. ActiveRecord also pertains to the model part of the MVC(Model)
37)What is the rake?and use of rake?
Ans:rake is ruby standlone command.It used to run the list of tasks.like rake db:migrate
38)What is the use of seeds in rails?
Ans: Rails gods have given us a way of feeding default values easily and quickly to a fresh installation. This is a normal Ruby program within the Rails environment. You have full access to all classes and methods of your application.
So you do not need to enter everything manually with rails console in order to make the records created in the section called “create” available in a new Rails application, but you can simply use the following file db/seeds.rb:
rake db:seed
39)What is the difference between application server and webserver?
Ans:apache, nginx, IIS are web servers
mongrel, webrick, phusion passenger are app servers
App server is something which works with particular programming language and parses and executes the code
since mongrel and webrick can only work with rails, so they are app servers
Web servers are servers which can take the request from the browser.
Web servers normally works on port 80 though we can change the port in configuration
since mongrel and webrick can take that request directly, so they can be thought of as web servers but web servers do have a lot of other functionality like request pipeline, load balancing etc.
App servers lack these functionalities.
About Mongrel server:
mongrel work as web as well as app server if you are talking about dev environment
but in production, mongrel alone can not work it will be too slow
so we need a web server in front of mongrel
40)Write the search dropdown in jquery?
41)What is the use of factorygirl in rails?
42)Hash with get maximun key and value in rails?
Ans:a = {"koti" => 95,"sam" => 99,"raghu" => 101,"raa" => 1}
a.max_by{|k,v| v}
=> ["raghu", 101]
43)Difference between rails2 and rails3?
Ans:
(1) Introduction of bundler (New way to manage your gem dependencies) *
(2) Gemfile and Gemfile.lock (Where all your gem dependencies lies, instead of environment.rb) *
(3) A new .rb file in config/ folder, named as application.rb
(Which has everything that previously environment.rb had) *
(4) Change in SQL Structure: Model.where(:activated => true) *
(5) All the mailer script will now be in app/mailers folder,
earlier we kept inside app/models. *
(6) Rails3-UJS support. for links and forms to work as AJAX,
instead of writing complex lines of code, we write :remote => true *
(7) HTML 5 support. *
(8) Changes in the model based validation syntax: validates :name, :presence => true *
(9) Ability to install windows/ruby/jruby/development/production specific gems to Gemfile.
group :production do
gem 'will_paginate'
end
44)Diffrerence between ruby1.9.3 and ruby2.0.0?
45)Difference between rails3 and rails4?
Ans:1. Ruby Versions
2. ‘Gemfile’
3. ‘Threadsafe’ by Default
4. No More vendor/plugins
5. New Testing Directories
6. Strong Parameters
7. Renamed Callback
10. Queuing system
13. Cache Digests (Russian Doll Caching)
14. Turbolinks
46)What is default scope in rails?
Ans:Scope is class method.retrieving and querying objects.
default_scope -> When ever active record is loaded that time only load default.
scope -> It will load when we call the scope method
class Post < ActiveRecord::Base
scope :published, where(status: 'published')
scope :draft, -> { where(status: 'draft') }
end
The main difference between both usages is that the :published condition is evaluated when the class is first loaded, whereas the :draft one is lazy evaluated when it is called. Because of that, in Rails 4 the first way is going to be deprecated which means you will always need to declare scopes with a callable object as argument. This is to avoid issues when trying to declare a scope with some sort of Time argument:
47)What is function of garbage collection in Ruby on Rails?
Ans:The Ruby runtime has a garbage collector. Depending on the runtime (JRuby/JVM generational GC, IronRuby/CLR generational GC, classic Ruby/mark-sweep GC) different algorithms are used. But the basics are pretty simple.
Garbage collection allows the removal of the pointer values that is left behind when the execution of the program ends.
-It frees the programmer from tracking the object that is being created dynamically on runtime.
-It provides a provision to remove the inaccessible objects from the memory and frees it so that other processes can use it.
-Garbage collection is used as:
x = Object.new
# this object is in use and it is residing in the memory. If it is not used then the status says
x = nil
# this means that the object can be removed from the memory and the memory can be freed for the other processes to run.
48)What is difference between render and redirect?
Ans:Redirect is used to tell the browser to issue a new request. Whereas, render only works in case the controller is being set up properly with the variables that needs to be rendered
49)What is orm?
Ans:ORM means object relational mapping.classes are directly mapped to tables,objects are mapped to rows and object attributes mapped to columns.
50)what is convention overconfiguration in rails?
51)How to define class?
52)What is REST in rails?
Ans:REpresentational State Transfer and describes resources (in our case URLs) on which we can perform actions. CRUD, which stands for Create, Read, Update, Delete, are the actions that we perform. Although, in Rails, REST and CRUD are bestest buddies, the two can work fine on their own. In fact, every time you have written a backend system that allows you to add, edit and delete items from the database, and a frontend that allows you to view those items, you have been working with CRUD
53)What is Ruby Gems?
Ans:- A gem is nothing more than a piece of ruby code packaged as a library so that it can be imported and used by others in their programs.
- A Ruby gem is therefore simply a library that is written in the ruby programming language.
54)What is Gemfile and Gemfile.lock?
Ans:The Gemfile is where you specify which gems you want to use, and lets you specify which versions. The Gemfile.lock file is where Bundler records the exact versions that were installed. This way, when the same library/project is loaded on another machine, running bundle install will look at the Gemfile.lock and install the exact same versions, rather than just using the Gemfile and installing the most recent versions. (Running different versions on different machines could lead to broken tests, etc.) You shouldn’t ever have to directly edit the lock file.
55)Ruby support multipleinheritance ? How can we implement?
Ans:
56)What is layouts?
Ans:Layouts are partial ruby/html files that are used to render the content pages.
There are placed in the folder: app/views/layouts
Items that you would typically put in this folder are things like headers/footers, navigation elements, etc.
57)What is the purpose of yield?
Ans:
58)What is observers and how can we will implement observers in rails?
Ans:
59)What is the ploymorphic associations? explain?
Ans:
60)What is minitest?
Ans:
61)What is unit testing?
Ans:
62)What is functional testing?
Ans:
63)What is integration testing?
Ans:
64)What are the joins in mysql and explain?
Ans:
65)What is the agile methodology?
Ans:
66)Difference between symbol and string?
Ans:
67)What is the request.xhr?
Ans:
68)How to Upload the images in rails?
Ans:
69)What is thread-safe?
Ans:
70)What is the thread?
Ans:
71)What is the difference between nil and false in ruby?
Ans:
72)What is the difference between git and github?
Ans:
73)What is the svn?
Ans:
74)How to change the one column all records change the uppercase in mysql?
Ans:
75)How Can We Make A Rails App Faster?
Ans:There are three ways to make your app faster: scaling, caching, and code optimization.
Scaling is easy these days. Heroku basically does it for you, and Hirefire makes the process automatic. You can learn more about autoscaling here. Other hosted environments offer similar solutions. By all means, use them if you can. But keep in mind that scaling is not a silver performance bullet. If your app serves the single request in 5 minutes, no amount of scaling will help. Also, with Heroku + Hirefire it's almost too easy to break the bank. I've seen Hirefire scaling up one of my apps to 36 dynos and having me to pay a whopping $3100 for that. Sure thing, I went ahead, scaled down manually to 2 dynos, and optimized the code instead.
Rails caching is also easy to do. Rails fragment caching is very good in Rails 4. Rails docs is an excellent source of info on caching. Another good read is Cheyne Wallace's article on Rails performance. It's also easy to setup Memcached these days. But as with scaling, caching is not an ultimate solution to performance problems. If your code is not working optimally, then you'll find yourself spending more and more resources on caching, to the point when caching stops making things faster.
The only reliable way to make your Rails app faster is code optimization. In Rails' case it's memory optimization. And, of course, if you follow my advice and avoid Rails to do things it's not designed for, you'll have even less code to optimize.
Let me tell you how to optimize your Rails app in 7 simple steps.
2.1 Avoid Memory Intensive Rails Features
Some features in Rails take more memory than necessary resulting in extra garbage collection runs. Here's the list.
2.1.1 Serializers
Serializer is a convenient way to represent strings from the database in a Ruby data type.
class Smth < ActiveRecord::Base
serialize :data, JSON
end
Smth.find(...).data
Smth.find(...).data = { ... }
But convenience comes with 3x memory overhead. If you store 100M in data column, expect to allocate 300M just to read it from the database.
Like learning from posts like this? Subscribe for more!
It's more memory efficient to do the serialization yourself like this:
class Smth < ActiveRecord::Base
def data
JSON.parse(read_attribute(:data))
end
def data=(value)
write_attribute(:data, value.to_json)
end
end
Like learning from posts like this? Subscribe for more!
This will have only 2x memory overhead. Some people, including myself, have seen Rails' JSON serializers leak memory, about 10% of data size per request. I do not understand the reason behind this. Neither do I have a reproducible case. If you experienced that, or know how to reproduce the leak, please let me know.
2.1.2 Active Record
It's easy to manipulate the data with ActiveRecord. But ActiveRecord is essentially a wrapper on top of your data. If you have a 1G of data in the table, ActiveRecord representation of it will take 2G and, in some cases, more. Yes, in 90% of cases that overhead is justified by extra convenience that you get. But sometimes you don't need it.
One example where you can avoid ActiveRecord's overhead is bulk updates. The code below will neither instantiate any model nor run validations and callbacks.
Book.where('title LIKE ?', '%Rails%').update_all(author: 'David')
Like learning from posts like this? Subscribe for more!
Behind the scenes it will just execute SQL UPDATE statement.
update books
set author = 'David'
where title LIKE '%Rails%'
Another example is iteration over a large dataset. Sometimes you need only the data. No typecasting, no updates. This snippet just runs the query and avoids ActiveRecord altogether:
result = ActiveRecord::Base.execute 'select * from books'
result.each do |row|
# do something with row.values_at('col1', 'col2')
end
Like learning from posts like this? Subscribe for more!
2.1.3 String Callbacks
Rails callbacks like before/after save, before/after action and so on are heavily used. But the way you write them may kill your performance. Here are the 3 ways you can write, for example, before_save callback:
before_save :update_status
before_save do |model|
model.update_status
end
before_save "self.update_status"
Like learning from posts like this? Subscribe for more!
First two ways are good to go, third is not. Why? Because to execute this callback Rails need to store execution context (variables, constants, global instances, etc.) that is present at the time of the callback. If your application is large, you end up copying a lot of data in the memory. Because callback can be executed any time, the memory cannot be reclaimed until your program finishes.
Having symbol callbacks saved me in one occasion 0.6 sec per request.
2.2 Write Less Ruby
This is my favorite step. As my university CS class professor liked to say, the best code is the one that doesn't exist. Sometimes the task at hand is better done with other tools. Most commonly it's a database. Why? Because Ruby is bad at processing large data sets. Like, very very bad. Remember, Ruby takes a large memory footprint. So, for example, to process 1G of data you might need 3G and more of memory. It will take several dozen seconds to garbage collect 3G. Good database can process the data in under a second. Let me show a few examples.
2.2.1 Attribute Preloading
Sometimes after denormalization attributes of the model get stored in another database table. For example, imagine we're building a TODO list that consists of task. Each task can be tagged with one or several tags. Denormalized data model will look like this:
Tasks
id
name
Tags
id
name
Tasks_Tags
tag_id
task_id
Like learning from posts like this? Subscribe for more!
To load tasks and their tags in Rails you would do this:
tasks = Task.find(:all, :include => :tags)
> 0.058 sec
Like learning from posts like this? Subscribe for more!
The problem with the code is that it creates an object for every Tag. That takes memory. Alternative solution is to do tag preloading in the database.
tasks = Task.select <<-END
*,
array(
select tags.name from tags inner join tasks_tags on (tags.id = tasks_tags.tag_id)
where tasks_tags.task_id=tasks.id
) as tag_names
END
> 0.018 sec
Like learning from posts like this? Subscribe for more!
This requires memory only to store an additional column that has an array of tags. No wonder it's 3x faster.
2.2.2 Data Aggregation
By data aggregation I mean any code that to summarizes or analyzes datasets. These operations can be simple sums, or anything more complex. Let's take group rank for example. Let's assume we have a dataset with employees, departments and salaries and we want to calculate the employee's rank within a department by salary.
SELECT * FROM empsalary;
depname | empno | salary
-----------+-------+-------
develop | 6 | 6000
develop | 7 | 4500
develop | 5 | 4200
personnel | 2 | 3900
personnel | 4 | 3500
sales | 1 | 5000
sales | 3 | 4800
Like learning from posts like this? Subscribe for more!
You can calculate the rank in Ruby:
salaries = Empsalary.all
salaries.sort_by! { |s| [s.depname, s.salary] }
key, counter = nil, nil
salaries.each do |s|
if s.depname != key
key, counter = s.depname, 0
end
counter += 1
s.rank = counter
end
Like learning from posts like this? Subscribe for more!
With 100k records in empsalary table this program finishes in 4.02 seconds. Alternative Postgres query using window functions does the same job more than 4 times faster in 1.1 seconds.
SELECT depname, empno, salary, rank()
OVER (PARTITION BY depname ORDER BY salary DESC)
FROM empsalary;
depname | empno | salary | rank
-----------+-------+--------+------
develop | 6 | 6000 | 1
develop | 7 | 4500 | 2
develop | 5 | 4200 | 3
personnel | 2 | 3900 | 1
personnel | 4 | 3500 | 2
sales | 1 | 5000 | 1
sales | 3 | 4800 | 2
Like learning from posts like this? Subscribe for more!
4x speedup is already impressive, but sometimes you get more, up to 20x. One example from my own experience. I had a 3-dimensional OLAP cube with 600k data rows. My program did slicing and aggregation. When done in Ruby, it took 1G of memory and finished in about 90 seconds. Equivalent SQL query finished in 5 seconds.
2.3 Fine-tune Unicorn
Chances are you are already using Unicorn. It's the fastest web server that you can use with Rails. But you can make it even faster.
2.3.1 App Preloading
Unicorn lets you preload your Rails application before forking worker processes. This has two advantages. First, with copy-on-write friendly GC (Ruby 2.0 and later) workers can share data loaded into memory by master process. That data will be transparently copied by an operating system in case worker changes it. Second, preloading reduces worker startup time. It's normal for Rails workers to be restarted (we'll talk about this in a moment), so the faster they restart, the better performance you get.
To turn on application preloading, simply include this line into your unicorn configuration file:
preload_app true
Like learning from posts like this? Subscribe for more!
2.3.2 GC Between Requests
Remember, GC amounts for up to 50% of your application runtime. That's not the only problem. GC is also unpredictable and happens exactly when you don't want it. What can we do about that?
First thing that comes to mind, what if we disable GC altogether? It turns out that's a bad idea. Your application can easily take 1G of memory before you notice. If you run several workers on your server, you will run out of memory even on a self-hosted hardware. Not to mention Heroku with its default 512M limit.
There's a better idea. If we cannot avoid GC, we can make it more predictable and run when there's nothing else to do. For example, between requests. It's actually easy to do this with Unicorn.
For Ruby < 2.1 there's OobGC Unicorn module:
require 'unicorn/oob_gc'
use(Unicorn::OobGC, 1) # "1" here means "force GC after every 1 request"
For Ruby >= 2.1 it's better to use [gctools](https://github.com/tmm1/gctools):
require 'gctools/oobgc'
use(GC::OOB::UnicornMiddleware)
Like learning from posts like this? Subscribe for more!
GC between requests has its caveats. Most importantly, this improves only perceived application performance. Meaning that the users will definitely see the optimization. You server hardware will actually have to do more work. Instead of doing GC as necessary, you will force your server to do it more often. So make sure you have enough resources to run GC and enough workers to serve incoming requests while other workers are busy with GC.
2.4 Limit Growth
I gave you several examples already where your application can grow up to 1G of memory. Taking a huge piece of memory by itself might not be a problem if you have a lot of memory. The real problem is that Ruby might not give that memory back to the operating system. Let me explain why.
Ruby allocates memory in two heaps. All Ruby objects go to Ruby's own heap. Each object has 40 bytes (on a 64-bit system) to store its data. When object needs to store more, it will allocate space in operating system's heap. When object is garbage collected and then freed, the space in the operating system's heap goes back to the operating system of course. But the space reserved for the object itself in Ruby heap is simply marked as free.
This means that Ruby heap can only grow. Imagine, you read 1 million rows, 10 columns in each row from the database. For that you allocate at least 10 million objects to store the data. Usually, Rails workers in average applications take 100M after start. To accommodate the data, the worker will grow by additional 400M (10 million objects, 40 bytes each). Even after you done with the data and garbage collect it, the worker will stay at 500M.
Disclaimer, Ruby GC does have the code to shrink the heap. I have yet to see that happen in reality because the conditions for heap to shrink rarely happen in production applications.
If your workers can only grow, the obvious solution is to restart the ones that get too big. Some hosting services, Heroku for example, do that for you. Let's see the other ways to do that.
2.4.1 Internal Memory Control
Trust in God, but lock your car. There're 2 types of memory limits your application can control on its own. I call them kind and hard.
Kind memory limit is the one that's enforced after each request. If worker is too big, it can quit and Unicorn master will start the new one. That's why I call it "kind", it doesn't abrupt your application.
To get the process memory size, use RSS metric on Linux and MacOS or OS gem on Windows. Let me show how to implement this limit in Unicorn configuration file:
class Unicorn::HttpServer
KIND_MEMORY_LIMIT_RSS = 150 #MB
alias process_client_orig process_client
undef_method :process_client
def process_client(client)
process_client_orig(client)
rss = `ps -o rss= -p #{Process.pid}`.chomp.to_i / 1024
exit if rss > KIND_MEMORY_LIMIT_RSS
end
end
Like learning from posts like this? Subscribe for more!
Hard memory limit is set by asking the operating system to kill your worker process if it grows too much. On Unix you can call setrlimit to set the RSS limit. To my knowledge, this only works on Linux. MacOS implementation was broken at some point. I'd appreciate any new information on that matter.
This the snippet from Unicorn configuration file with the hard limit:
after_fork do |server, worker|
worker.set_memory_limits
end
class Unicorn::Worker
HARD_MEMORY_LIMIT_RSS = 600 #MB
def set_memory_limits
Process.setrlimit(Process::RLIMIT_AS, HARD_MEMORY_LIMIT * 1024 * 1024)
end
end
Like learning from posts like this? Subscribe for more!
2.4.2 External Memory Control
Self-control does not save you from occasional OOM (out of memory). Usually you should setup some external tools. On Heroku there's no need as they have their own monitoring. But if you're self-hosting, it's a good idea to use monit, god, or any other monitoring solution.
2.5 Tune Ruby GC
In some cases you can tune Ruby GC to improve its performance. I'd say that these GC tuning is becoming less and less important, as the default settings in Ruby 2.1 and later are already good for most people.
To fine-tune GC you need to know how it works. This is a separate topic that does not belong to this article. To learn more, read a thorough Demystifying the Ruby GC article by Sam Saffron. In my upcoming Ruby Performance book I dig into even deeper details of Ruby GC. Subscribe here and I will send you email when I finish at least the beta version of the book.
My best advice is, probably, do not change GC settings unless you know what you are doing and have a good theory on how that can improve performance. This is especially true for Ruby 2.1 and later users.
I know only of one case when GC tuning helps. It's when you load large amounts of data in a single go. Here's when you can decrease the frequency of GC runs by changing the following environment variables: RUBY_GC_HEAP_GROWTH_FACTOR, RUBY_GC_MALLOC_LIMIT, RUBY_GC_MALLOC_LIMIT_MAX, RUBY_GC_OLDMALLOC_LIMIT, and RUBY_GC_OLDMALLOC_LIMIT.
Note, these are variables from Ruby 2.1 and later. Previous versions have less variables, and often use different names.
RUBY_GC_HEAP_GROWTH_FACTOR, default value 1.8, controls how much the Ruby heap grows when there's not enough heap space to accommodate new allocations. When you work with large amounts of objects, you want your heap space grow faster. In this case, increase the heap growth factor.
Memory limits define how often GC is triggered when you allocate memory on operating system's heap. Default limit values in Ruby 2.1 and later are:
New generation malloc limit RUBY_GC_MALLOC_LIMIT 16M
Maximum new generation malloc limit RUBY_GC_MALLOC_LIMIT_MAX 32M
Old generation malloc limit RUBY_GC_OLDMALLOC_LIMIT 16M
Maximum old generation malloc limit RUBY_GC_OLDMALLOC_LIMIT_MAX 128M
Like learning from posts like this? Subscribe for more!
Let me briefly explain what these values mean. With the configuration as above, for every 16M to 32M allocated by new objects, and for every 16M to 128M allocated by old objects ("old" means that an object survived at least 1 garbage collection call) Ruby will run GC. Ruby dynamically adjust the current limit value depending on your memory allocation pattern .
So, if you have small number of objects that take large amounts of memory (for example, read large files into one string), you can increase the limits to trigger GC less often. Remember to increase all 4 limits, better proportionally to their default values.
My advice, however, differs from what other people recommend. What worked for me might not work for you. Here are the articles describing what worked for Twitter and for Discourse.
2.6 Profile
Sometimes none of the ready-to-use advice can help you, and you need to figure out what's wrong yourself. That's when you use the profiler. Ruby-Prof is what everybody uses in Ruby world.
To learn more on profiling, read Chris Heald's and my own articles on using ruby-prof with Rails. Later also has, albeit outdated, advice on memory profiling.
2.7 Write Performance Tests
The last, but by all means not the least important step in making Rails faster is to make sure that slowdowns do not happen again after you fix them. Rails 3.x has performance testing and profiling framework bundled in. For Rails 4 you can use the same framework extracted into rails-perftest gem.
3 Closing Thoughts
It's not possible to cover everything on Ruby and Rails performance optimization in one post. So lately I decided to summarize my knowledge in a book. If you find my advice helpful, please sign up for the mailinglist and I'll notify you once I have an early preview of this book ready. Now, go ahead, and make your Rails application faster!
Ans:
i)Include makes the module methods are available instance of the class.
1)Not available at the class level
2)Available at the instance level
ii)extend makes module methods are available class itself.
1)Not available at the class level
2)Available at the instance level
here is a big difference between include and extend in Ruby. Let me show you some code to explain it :
Exampl1:
module Printable
def self.class_method_x
p 'class_method_x'
end
def instance_method_y
p 'instance_method_y'
end
end
—
class ExtendDocument
extend Printable
end
—
class IncludeDocument
include Printable
end
First round, on the Printable module :
Printable.class_method_x
# => "class_method_x"
—
Printable.instance_method_y
# => NoMethodError: undefined method `instance_method_y' for Printable:Module
Second round, on ExtendDocument :
ExtendDocument.class_method_x
# => NoMethodError: undefined method `class_method_x' for ExtendDocument:Class
—
ExtendDocument.instance_method_y
# => "instance_method_y"
And on an instance of ExtendDocument :
ExtendDocument.new.class_method_x
# => NoMethodError: undefined method `class_method_x' for #<ExtendDocument:0x007fe9e308ac08>
—
ExtendDocument.new.instance_method_y
# => NoMethodError: undefined method `instance_method_y' for #<ExtendDocument:0x007fe9e3080370>
Oops, nothing is working !
Last round, on IncludeDocument :
IncludeDocument.class_method_x
# => NoMethodError: undefined method `class_method_x' for IncludeDocument:Class
IncludeDocument.instance_method_y
# => NoMethodError: undefined method `instance_method_y' for IncludeDocument:Class
And on an instance of IncludeDocument :
IncludeDocument.new.class_method_x
# => NoMethodError: undefined method `class_method_x' for #<IncludeDocument:0x007fe9e3056480>
IncludeDocument.new.instance_method_y
# => "instance_method_y"
As you’ve probably noticed, Extend a module inside a class will add the instance methods defined in the module to the extended class.
The Include will add the instance methods defined in the module to the instances of the class including the module.
Example2
module ReusableModule
def module_method
puts "Module Method: Hi there!"
end
end
class ClassThatIncludes
include ReusableModule
end
class ClassThatExtends
extend ReusableModule
end
puts "Include"
ClassThatIncludes.new.module_method # "Module Method: Hi there!"
puts "Extend"
ClassThatExtends.module_method
2)How to convert the string to integer in jquery?
x = parseInt("10")
3)What are the changes in ruby2.2.0?
i)Ruby’s Garbage Collector is now able to collect Symbol type objects. This reduces memory usage of Symbols; because GC was previously unable to collect them before 2.2. Since Rails 5.0 will require Symbol GC, it will support only Ruby 2.2 or later. (See Rails 4.2 release post for details.)
Also, a reduced pause time thanks to the new Incremental Garbage Collector will be helpful for running Rails applications. Recent developments mentioned on the Rails blog suggest that Rails 5.0 will take advantage of Incremental GC as well as Symbol GC.
ii)Another feature related to memory management is an additional option for configure.in to use jemalloc Feature #9113. This feature is still experimental and currently disabled by default until we gather performance data and more use cases. When we are convinced of the benefits, this feature will be enabled by default.
4)What is the tubolinks?
Ans:Turbolinks is a gem that will be included by default in new Rails 4 applications. It’s also compatible with Rails 3 so we can use it in our current apps too. This gem can make our applications appear faster to the user by using JavaScript to replace the HTML body of new pages instead of relying on a full page load.
Load a fresh version of a page from the server:
page:before-change a Turbolinks-enabled link has been clicked (see below for more details)
page:fetch starting to fetch a new target page
page:receive the page has been fetched from the server, but not yet parsed
page:before-unload the page has been parsed and is about to be changed
page:after-remove a node (stored in event.data) has been removed from the DOM and should be cleaned up (jQuery data is cleaned up automatically)
page:change the page has been changed to the new version (and on DOMContentLoaded)
page:update is triggered alongside both page:change and jQuery's ajaxSuccess (if jQuery is available - otherwise you can manually trigger it when calling XMLHttpRequest in your own code)
page:load is fired at the end of the loading process.
5)What is the strong parameterized?
Ans: Action Controller parameters are forbidden to be used in Active Model mass assignments until they have been whitelisted. This means you'll have to make a conscious choice about which attributes to allow for mass updating and thus prevent accidentally exposing that which shouldn't be exposed.
gem 'strong_parameters'
The strong_parameters gem is an improvement over attr_accessible to securely handle mass assignment even when you have complex authorization logic. The functionality will likely be added to Rails 4
6)What are the acess speicifiers in rails?
Ans:Public,Private,Protected
i)Public - can be called from anywhere
ii)Private - The method cannot be called outside class scope. The object send message to itself
ex: the baker has bake method as public but break_eggs is private
iii)Protected - You can call an object's protected methods as long as the default object self is an instance of the same clas as the object whose method you're calling
ex: with n protected method, c1 can ask c2 to execute c2.n, because c1 e c2 are both instances of the same class
And last but not least:
Inheritance: Subclasses inherit the method-access rules of their superclass
if "class D < C", then D will exhibit the same access behaviour as instances of C
i)Public methods can be called by all objects and subclasses of the class in which they are defined in.
ii)Protected methods are only accessible to objects within the same class.
iii)Private methods are only accessible within the same instance.
i)public - can be accessed by any object (e.g. Obj.new.public_method)
ii)protected - can only be accessed from within the object itself, as well as any subclasses
iiii)private - same as protected, but the method doesn't exist in subclasses
7)What is the Habtm?
Ans:It specifies many to many relationship with another class.
This associates two classes via an intermediate join table. Unless the join table is explicitly specified as an option, it is guessed using the lexical order of the class names. So a join between Developer and Project will give the default join table name of “developers_projects” because “D” precedes “P” alphabetically.
8)How to get the second maxmimun highet age from user table?
Ans:select * from users order by salary asc limit n-l,1;
n -> Total number of rows
l-> Which maximum number is required
9)How to write the class methods?
Ans:class A
def first_method
end
end
a = A.new.first_method
10)What is the module?
Ans:A Module is a collection of methods and constants. The methods in a module may be instance methods or module methods. Instance methods appear as methods in a class when the module is included, module methods do not. Conversely, module methods may be called without creating an encapsulating object, while instance methods may not. (See Module#module_function.)
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║ ║ class ║ module ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated ║ can *not* be instantiated ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage ║ object creation ║ mixin facility. provide ║
║ ║ ║ a namespace. ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass ║ module ║ object ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ consists of ║ methods, constants, ║ methods, constants, ║
║ ║ and variables ║ and classes ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods ║ class methods, ║ module methods, ║
║ ║ instance methods ║ instance methods ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance ║ inherits behavior and can ║ No inheritance ║
║ ║ be base for inheritance ║ ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion ║ cannot be included ║ can be included in classes and ║
║ ║ ║ modules by using the include ║
║ ║ ║ command (includes all ║
║ ║ ║ instance methods as instance ║
║ ║ ║ methods in class/module) ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension ║ can not extend with ║ module can extend instance by ║
║ ║ extend command ║ using extend command (extends ║
║ ║ (only with inheritance) ║ given instance with singleton ║
║ ║ ║ methods from module) ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝
11)Jquery click and bind functions explain?
Ans: .bind() method is used for attaching an event handler directly to elements
$("p").bind("click", function(){
alert("The paragraph was clicked.");
});
12)What is the Russian Doll Caching?
Ans:The technique of nesting fragment caches to maximize cache hits is known as russian doll caching. By nesting fragment caches, it ensures that caches can be reused even when content changes. When a change occurs to the top-most fragment cache, only that cache must be expired. Every nested cache of the parent can be reused, which provides a significant performance increase. A change to the most nested fragment cache would start a chain reaction to expire all parent caches.
et's look at an example of using the russian doll caching technique. We are going to have a Team model which has many Members. When we display a team, we must also render out member names and biographies.
class Team < ActiveRecord::Base
has_many :members
end
class Member < ActiveRecord::Base
belongs_to :team, touch: true
end
Adding the :touch option to belongs_to :team on the Member model, ensures that when a member is changed, we update the Team model as well. This is essential for using russian doll caching, as you must be able to break parent caches once children are modified.
The view template matches the hierarchy of the models. The team is the parent fragment cache, while the collection of members are its children.
<!-- app/views/teams/show.html.erb -->
<% cache @team do%>
<h1>Team: <%= @team.name %></h1>
<%= render @team.members %>
<% end %>
<!-- app/views/members/_member.html.erb -->
<% cache member do %>
<div class='member'>
<%= member.name %>
<p><%= member.bio %></p>
</div>
<% end %>
If we had a team with two members, a total of of 3 fragment caches would be written:
views/members/1-20121220141922
views/members/2-20121220141922
views/teams/2-20121220141922
The key is composed of the concatenation of the view path and the model cache_key. The cache_key returns a combination of the id of a model, plus a timestamp of the last time it was updated. This combination ensures a cache will always be expired if a model is updated.
The above technique will work seamlessly until you have to modify the template of one of the fragments. Since the template is not taken into account in the fragment cache key, any changes to the template will not expire the cache. This quickly progresses in prefixing the fragment cache keys with a version , so that an expiration will be forced. A change in a nested fragment version, will result in all parent versions needing a version bump also.
<!-- app/views/teams/show.html.erb -->
<% cache ["v1", @team] do%>
<h1>Team: <%= @team.name %></h1>
<%= render @team.members %>
<% end %>
<!-- app/views/members/_member.html.erb -->
<% cache ["v1", member] do %>
<div class='member'>
<span><%= member.name %></span>
<p><%= member.bio %></p>
</div>
<% end %>
The above version prefixing results in the following fragment caches:
views/v1/members/1-20121220141922
views/v1/members/2-20121220141922
views/v1/teams/2-20121220141922
Cache Digests
If someone forgets to change the version number of a template, and all its dependents, then the entire russian doll caching technique breaks down quickly. This happens easily, as there is no visual reference of template dependencies. For example, looking at the app/views/teams/show.html.erb template, there is no indication that each member has its own fragment cache.
Rails 4 solves this problem with cache digests. A call to #cache in your views will now suffix a digest of the template and its dependencies. No longer will you need to worry about fragment cache dependencies and versioning!
Let's take a look at out last example, now using cache digests:
<!-- app/views/teams/show.html.erb -->
<% cache @team do%>
<h1>Team: <%= @team.name %></h1>
<%= render @team.members %>
<% end %>
<!-- app/views/members/_member.html.erb -->
<% cache member do %>
<div class='member'>
<span><%= member.name %></span>
<p><%= member.bio %></p>
</div>
<% end %>
This results in the following fragment caches, now suffixed with an MD5 of the template itself:
13)What is the difference between proc and lamda?
Ans:1. Proc doesn't check the parameters passed, but Lambda does
> proc1 = Proc.new { |a, b| a + 5 }
> proc1.call(2) # call with only one parameter
=> 7 # no error, unless the block uses the 2nd parameter
> lambda1 = lambda { |a, b| a + 5 }
> lambda1.call(2)
ArgumentError: wrong number of arguments (1 for 2)
Proc will throw error only if the block uses the second param.
> proc2 = Proc.new { |a, b| a + b }
> proc2.call(2) # call with only one parameter
TypeError: nil can't be coerced into Fixnum
2. Proc returns from the calling method, while Lambda doesn't
> def meth1
> Proc.new { return 'return from proc' }.call
> return 'return from method'
> end
> puts meth1
return from proc
> def meth2
> lambda { return 'return from lambda' }.call
> return 'return from method'
> end
> puts meth2
return from method
If they are not called inside a method,
> proc1 = Proc.new { return "Thank you" }
> proc1.call
LocalJumpError: unexpected return
> lambda1 = lambda { return "Thank you" }
> lambda1.call
i)Procs, short for procedures, act similar to blocks, but can be saved as variables and reused. Think of them as blocks you can call over and over again on multiple arrays.
ii)Lambdas are very similar to procs in terms of functionality. However, they have a few key differences. Lambdas check the number of arguments passed and will return an error if you try to pass the wrong number (while procs set extra variables to nil). The other difference is that lambdas can handle a return function, whereas procs will return an error.
14)What is the scope?
Ans:Scope is a class method for retrieving and querying objects.
Scopes are nothing more than SQL scope fragments. By using these fragments one can cut down on having to write long queries each time you access content.
i)default_scope -->When the model is loaded at the same time only it will load.
ii)scope --> It will load when we are calling the scope
class Article < ActiveRecord::Base
default_scope where(:published => true) --> default scope
scope :active, -> { where state: 'active' } --> Normal scope
end
15)What is the caching?
Ans:Rails having 3 types of caching
i)Page Caching --> public/college.html -> (cache page)
ii)Action Caching -> tmp/cache/4F1 -> 'F' it will generate
iii)Fragment Caching -> tmp/cache/B7C
Gemfile
i)gem 'actionpack-page_caching'
ii)gem 'actionpack-action_caching'
Rails caching is disabled by default in the development environment. Make sure you have below the parameter value below set to true in your Rails app config file.
#Inside config/environments/development.rb
config.action_controller.perform_caching = true
Rails caching is enabled in production mode by default.
Rails Page Caching
In Rails Page Caching, whenever a request is sent to the server, the Rails server would check for the cached page and if that exists it would be served. If it does not exist, Rails server generates the page & cache it. Hence the Rails app won’t have to generate it again during the next request.
Eg
Class UserController < ActionController
caches_page :profile
def profile
@user = current_user
end
end
To expire the cache when an update is made, we will have to call an expire_page helper method.
Eg
Class UserController < ActionController
caches_page :profile
def profile
@user = current_user
end
def update
expire_page :action => profile
end
end
Here it is assumed that update action is being called when the page is updated. expire_page inside the action makes sure the cached page is purged & new cached page is created during the next call to profile action.
This type of caching in Rails is lightning fast, but one main disadvantage of this is that this can’t be used for caching every page. As the requests don’t go to the Rails app, the authentication and access restrictions using before_filter won’t work if page caching is used.
The above example is probably the wrong usage of the Rails page cache. You can see that page served by ‘profile’ action has dependency on the current_user (assume it to be logged in user).
Let’s say user_1 is the first user to view the page. The page will be generated & cached with contents for user_1 . If user_2 tries to go to his profile page, he will see user_1 content on it. This is plain wrong :) .
Rails Action Caching
While Rails Page caching caches the complete page (& the request never reaches the Rails controller), Rails action caching only caches the activities happening inside the action. For e.g., if a Rails action is fetching data from database & then rendering a view, these items would be cached & directly used the next time the cache is accessed.
In Rails Action Caching, the disadvantages of Rails Page Caching won’t be a problem as all the requests will be sent to the appropriate Rails action. Hence the authentication and access restrictions using the before_filters can be applied before serving a page.
The code for Rails Action Caching is similar to Rails Page Caching
Class UserController<ActionController
before_filter :authenticate
caches_action :profile
def profile
@user = current_user
end
def update
expire_action :action => profile
end
end
Rails Fragment Caching
Rails Fragment Caching is mainly used for dynamic pages. In this type of caching, fragments of a page can be cached and expired.
Consider an example in which an article is posted to a blog and a reader wants to post a comment to it. Since the article is the same this can be cached while the comments will always be fetched from the database. In this case we can use Rails Fragment Caching for article.
P.S. – Rails Fragment Caching is best done in the Views. The code snippet below is part of Rails View unlike previous examples where code snippets are part of Rails Controllers.
<% cache("article") do %>
<%= render article %>
<% end %>
<% @article.comments.each do |comments| %>
<%= comments.user_name %>
<%= comments.user_comment %>
<% end %>
The highlighted code will cache whatever is between `cache(‘article’) do … end`. The name `article` is used to reference the fragment cache block.
The cached fragments can be expired by using expire_fragment()
Class UserController < ActionController
def profile
@user = current_user
end
def update
expire_fragment("article")
end
end
Rails SQL Caching
SQL Caching will cache any SQL results performed by the Active Records or Data mappers automatically in each action . So, the same query doesn’t hit the database again – thereby decreasing the load time.
Eg:
Class ArticleController < ActionController
def index
@artilces = Article.all
# Run the same query again
@articles = Article.all # will pull the data from the memory and not from DB
end
end
This caching scope includes only the action in which the query is executed. In the above example, executing Article.all the second time will used cached result. But outside the action, the same query will hit the database.
Rails cache explained with an example blog app
16)What are the associations?
Ans: Association is a connection between two Active Record models
i)belongs_to -->
A belongs_to association sets up a one-to-one connection with another model, such that each instance of the declaring model "belongs to" one instance of the other model
example:
class Order < ActiveRecord::Base
belongs_to :customer
end
ii)has_one -->
A has_one association also sets up a one-to-one connection with another model, but with somewhat different semantics (and consequences). This association indicates that each instance of a model contains or possesses one instance of another model. For example, if each supplier in your application has only one account, you'd declare the supplier model like this:
class Supplier < ActiveRecord::Base
has_one :account
end
iii)has_many -->
A has_many association indicates a one-to-many connection with another model. You'll often find this association on the "other side" of a belongs_to association. This association indicates that each instance of the model has zero or more instances of another model. For example, in an application containing customers and orders, the customer model could be declared like this:
class Customer < ActiveRecord::Base
has_many :orders
end
iv)has_many :through -->
A has_many :through association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model. For example, consider a medical practice where patients make appointments to see physicians. The relevant association declarations could look like this:
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, through: :appointments
end
v)has_one :through -->
A has_one :through association sets up a one-to-one connection with another model. This association indicates that the declaring model can be matched with one instance of another model by proceeding through a third model. For example, if each supplier has one account, and each account is associated with one account history, then the supplier model could look like this:
class Supplier < ActiveRecord::Base
has_one :account
has_one :account_history, through: :account
end
class Account < ActiveRecord::Base
belongs_to :supplier
has_one :account_history
end
class AccountHistory < ActiveRecord::Base
belongs_to :account
end
vi)has_and_belongs_to_many -->
A has_and_belongs_to_many association creates a direct many-to-many connection with another model, with no intervening model. For example, if your application includes assemblies and parts, with each assembly having many parts and each part appearing in many assemblies, you could declare the models this way:
class Assembly < ActiveRecord::Base
has_and_belongs_to_many :parts
end
class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
end
jointable -> assemblies_parts
17)what is the mvc?
Ans:
The MVC() framework is an age-old architecture pattern that works very well for most applications. Rails has adopted the MVC pattern in its inherent design.
Stated Simply:
a) Model — is where the data is — the database
b) Controller — is where the logic is for the application
c) View — is where the data is used to display to the user
Process of mvc -> once request come from the browser first it will go to the routes file after it will check the corresponding controller action and controller will interact to the model and model connect to the database.after retriveing the data will send to controller and controller send back the view and display the browser.
18)What are variables in rails?
Ans:i)Local variables:Local variables begin with a lowercase letter or _. The scope of a local variable ranges from class, module, def, or do to the corresponding end or from a block's opening brace to its close brace {}.
ii)class variables:Class variables are created with the prefix ‘@@’ and are shared by all objects in a class.
!/usr/bin/ruby
class Customer
@@no_of_customers=0
def initialize(id, name, addr)
@cust_id=id
@cust_name=name
@cust_addr=addr
end
def display_details()
puts "Customer id #@cust_id"
puts "Customer name #@cust_name"
puts "Customer address #@cust_addr"
end
def total_no_of_customers()
@@no_of_customers += 1
puts "Total number of customers: #@@no_of_customers"
end
end
# Create Objects
cust1=Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2=Customer.new("2", "Poul", "New Empire road, Khandala")
# Call Methods
cust1.total_no_of_customers()
cust2.total_no_of_customers()
Here @@no_of_customers is a class variable. This will produce the following result:
Total number of customers: 1
Total number of customers: 2
iii)global variables:Global variables are declared with the ‘$’ symbol and can be declared and used anywhere within your program. You should use them sparingly to never.
$global_variable = 10
class Class1
def print_global
puts "Global variable in Class1 is #$global_variable"
end
end
class Class2
def print_global
puts "Global variable in Class2 is #$global_variable"
end
end
class1obj = Class1.new
class1obj.print_global
class2obj = Class2.new
class2obj.print_global
Here $global_variable is a global variable. This will produce the following result:
NOTE: In Ruby you CAN access value of any variable or constant by putting a hash (#) character just before that variable or constant.
Global variable in Class1 is 10
Global variable in Class2 is 10
iv)instance variables:Instance variables are created with the prefix ‘@’ and belong to a single object within a class.
ex:class Customer
def initialize(id, name, addr)
@cust_id=id
@cust_name=name
@cust_addr=addr
end
def display_details()
puts "Customer id #@cust_id"
puts "Customer name #@cust_name"
puts "Customer address #@cust_addr"
end
end
# Create Objects
cust1=Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2=Customer.new("2", "Poul", "New Empire road, Khandala")
# Call Methods
cust1.display_details()
cust2.display_details()
Here, @cust_id, @cust_name and @cust_addr are instance variables. This will produce the following result:
Customer id 1
Customer name John
Customer address Wisdom Apartments, Ludhiya
Customer id 2
Customer name Poul
Customer address New Empire road, Khandala
19)How to set the tablename in rails?
Ans:
class Countries < ActiveRecord::Base
self.table_name = "cc"
end
20)What is the difference between ruby hash and parameters hash?
Ans:
21)How to call the class methods in rails?
Ans:
class Sample
def koti
p "hello koti"
end
end
a = Sample.new()
a.koti
22)What is the difference between mysql and postgresql?
Mysql
i)MySQL is a fast, easy-to-use RDBMS being used for many small and big businesses. MySQL is developed, marketed, and supported by MySQL AB, which is a Swedish company. MySQL is becoming so popular because of many good reasons:
ii)MySQL is released under an open-source license. So you have nothing to pay to use it.
iii)MySQL is a very powerful program in its own right. It handles a large subset of the functionality of the most expensive and powerful database packages.
iv)MySQL uses a standard form of the well-known SQL data language.
v)MySQL works on many operating systems and with many languages including PHP, PERL, C, C++, JAVA, etc.
v)MySQL works very quickly and works well even with large data sets.
vi)MySQL is very friendly to PHP, the most appreciated language for web development.
vii)MySQL supports large databases, up to 50 million rows or more in a table. The default file size limit for a table is 4GB, but you can increase this (if your operating system can handle it) to a theoretical limit of 8 million terabytes (TB).
viii)MySQL is customizable. The open-source GPL license allows programmers to modify the MySQL software to fit their own specific environments.
Postgresql:
i)PostgreSQL is a powerful, open source object-relational database system. It has more than 15 years of active development and a proven architecture that has earned it a strong reputation for reliability, data integrity, and correctness.
ii)Complex SQL queries
iii)SQL Sub-selects
iv)Foreign keys
v)Trigger
vi)Views
vii)Transactions
viii)Multiversion concurrency control (MVCC)
ix)Streaming Replication (as of 9.0)
x)Hot Standby (as of 9.0)
***postgres is secure, fast, n full of features but comparatively tricky to use.
23)What is the cronjob?What gem used for cronjob?
Ans:Cron is a piece of software written for *nix-type operating systems to help with the scheduling of recurring tasks. You may want to use cron to schedule certain recurring actions in your Rails application.Cron is great for handling recurring tasks
Gem Name:gem 'whenever', :require => false
wheneverize .
config/schedule.rb
example:
every 3.hours do
runner "MyModel.some_process"
rake "my:rake:task"
end
24)How to implement custom validation in rails?
Ans:When we are bulit in rails application.the validation helpers are not sufficient we can write the custom validations using
Custom validators are classes that extend ActiveModel::Validator
Example:
class Invoice < ActiveRecord::Base
validate :expiration_date_cannot_be_in_the_past,
:discount_cannot_be_greater_than_total_value
def expiration_date_cannot_be_in_the_past
if !expiration_date.blank? and expiration_date < Date.today
errors.add(:expiration_date, "can't be in the past")
end
end
def discount_cannot_be_greater_than_total_value
if discount > total_value
errors.add(:discount, "can't be greater than total value")
end
end
25)Rails resource :photos -> list out all the routes
Ans:
HTTP Verb Path Controller#Action Used for
GET /photos photos#index display a list of all photos
GET /photos/new photos#new return an HTML form for creating a new photo
POST /photos photos#create create a new photo
GET /photos/:id photos#show display a specific photo
GET /photos/:id/edit photos#edit return an HTML form for editing a photo
PATCH/PUT /photos/:id photos#update update a specific photo
DELETE /photos/:id photos#destroy delete a specific photo
26)What is the callbacks? How many callbacks are available?
Ans:Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.
Types of Callbacks:
i)before_validation
ii)after_validation
iii)before_save
iv)around_save
v)before_create
vi)around_create
vii)after_create
viii)after_save
ix)before_update
x)around_update
xi)after_update
xii)after_commit/after_rollback
27)What is the filters? How many filters are available?ns
Ans:
Rails 3-> Rails4 (changeing filters to actions)
i)Filters are methods that are run before, after or "around" a controller action.
ii)Filters are inherited, so if you set a filter on ApplicationController, it will be run on every controller in your application.
Types of Filters:
i)before_filter :get_user_name --->"Before" filters may halt the request cycle. A common "before" filter is one which requires that a user is logged in for an action to be run
class ApplicationController < ActionController::Base
before_action :require_login
private
def require_login
unless logged_in?
flash[:error] = "You must be logged in to access this section"
redirect_to new_login_url # halts request cycle
end
end
end
ii)after_filter :update_user_details ---> After" filters are similar to "before" filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, "after" filters cannot stop the action from running
iii)around_filter :update_tarnsaction --->
"Around" filters are responsible for running their associated actions by yielding, similar to how Rack middlewares work.
class ChangesController < ApplicationController
around_action :wrap_in_transaction, only: :show
private
def wrap_in_transaction
ActiveRecord::Base.transaction do
begin
yield
ensure
raise ActiveRecord::Rollback
end
end
end
end
28)What is the difference between the collection and memember in routes?
Ans:A member route will require an ID, because it acts on a member. A collection route doesn't because it acts on a collection of objects.
resources :photos do
member do
get :preview
end
end
resources :photos do
collection do
get :search
end
end
URL Helper Description
----------------------------------------------------------------------------------------------------------------------------------
member /photos/1/preview preview_photo_path(photo) Acts on a specific resource so required id (preview specific photo)
collection /photos/search search_photos_url Acts on collection of resources(display all photos)
29)What is the nested resoures?
Ans:Ruby on Rails allows you to set up nested resources. For instance in the "Getting started" guide where you build a very simple blog, Post and Comment are nested resources. Indeed, it is impossible to consider a lone comment without any post. A Comment belongs to a Post. Resources being referenced by URIs, the setup of nested resources in RoR is done through routing as following:
resources :posts do
resources :comments
end
30)What is the use of concerns in rails4?
Ans: Main use of concerns are implement the modules.The Rails Concern are used to DRYING the code for both models and controllers.So just by including the module,either in model/controller you get the methods and you can call them just like you call it usually as if they are defined within the controller/model.
1) DRYing up model codes
Consider a Article model, a Event model and a Comment model. An article or an event has many comments. A comment belongs to either Article or Event.
Traditionally, the models may look like this:
Comment Model:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
Article Model:
class Article < ActiveRecord::Base
has_many :comments, as: :commentable
def find_first_comment
comments.first(created_at DESC)
end
def self.least_commented
#return the article with least number of comments
end
end
Event Model
class Event < ActiveRecord::Base
has_many :comments, as: :commentable
def find_first_comment
comments.first(created_at DESC)
end
def self.least_commented
#returns the event with least number of comments
end
end
As we can notice, there is a significant piece of code common to both Event and Article. Using concerns we can extract this common code in a separate module Commentable.
For this create a commentable.rb file in app/model/concerns.
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments, as: :commentable
end
# for the given article/event returns the first comment
def find_first_comment
comments.first(created_at DESC)
end
module ClassMethods
def least_commented
#returns the article/event which has the least number of comments
end
end
end
And Now your models look like this :
Comment Model:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
Article Model:
class Article < ActiveRecord::Base
include Commentable
end
Event Model:
class Event < ActiveRecord::Base
include Commentable
end
2) Skin-nizing Fat Models.
Consider a Event model. A event has many attenders and comments.
Typically, the event model might look like this
class Event < ActiveRecord::Base
has_many :comments
has_many :attenders
def find_first_comment
# for the given article/event returns the first comment
end
def find_comments_with_word(word)
# for the given event returns an array of comments which contain the given word
end
def self.least_commented
# finds the event which has the least number of comments
end
def self.most_attended
# returns the event with most number of attendes
end
def has_attendee(attendee_id)
# returns true if the event has the mentioned attendee
end
end
Models with many associations and otherwise have tendency to accumulate more and more code and become unmanageable.Concerns provide a way to skin-nize fat modules making them more modularized and easy to understand.
The above model can be refactored using concerns as below: Create a attendable.rd and commentable.rb file in app/model/concern/event folder
attendable.rb
module Attendable
extend ActiveSupport::Concern
included do
has_many :attenders
end
def has_attender(attender_id)
# returns true if the event has the mentioned attendee
end
module ClassMethods
def most_attended
# returns the event with most number of attendes
end
end
end
commentable.rb
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments
end
def find_first_comment
# for the given article/event returns the first comment
end
def find_comments_with_word(word)
# for the given event returns an array of comments which contain the given word
end
module ClassMethods
def least_commented
# finds the event which has the least number of comments
end
end
end
And now using Concerns , your Event model reduces to
class Event < ActiveRecord::Base
include Commentable
include Attendable
end
* While using concerns its advisable to go for 'domain' based grouping rather than 'technical' grouping. Domain Based grouping is like 'Commentable', 'Photoable', 'Attendable'. Technical grouping will mean 'ValidationMethods', 'FinderMethods' etc
31)What are the selectors in jquery?
Ans:i)class,ii)id
32)What is the difference between has_and_belongs_to_many and has_many through?
Ans:has_and_belongs_to_many doenot require model.where has_many through require the model.
33)What is the capistrano?How to deploy the using capistrano in rails?
Ans:Capisrano is a ruby gem.deploying the code from developer to desktop to server
34)What is the bdd and tdd?
Ans:BDD ---> Behaviour Driven Development ---> Cucumber
TDD ----> Test Driven Development ---> Rspec --->TDD is all about writing tests first. This basically forces you to write your own client before you write your application code. The cycle is generally write a test for an API that doesn't exist, run the test expecting it to fail, go write your API code, run your test again and make sure it passes. Then write your next test... and so on
i). BDD focuses on specifying what will happen next. where as TDD focuses on setting up a set of conditions and then looking at the output.
ii). BDD specifies behaviours while TDD specifies outcomes.
iii). BDD can be layered, while outcomes(TDD) cannot.
iv). TDD is for testing and we can’t perform Design process, Requirements capturing and Behavior specification in TDD, but these can be possible in BDD.
v). BDD is mainly used as a communication tool. its main goal is write executable specifications which can be understood by the domain experts.
vi). the main difference between BDD and TDD is wording. as these are important for communicating your intend.
BDD
Given the user is logged in
*** test code***
And they are an administrator
***test code***
When the deleteUser is called
***test code***
Then the user will be removed from the system
***test code***
And they will also be removed from any groups they belong to
***test code***
TDD (done badly)
Test SomeClass delete method()
***test code***
The top one can be read and understood by a domain expert, the bottom one the reader would have to guess the intended behaviour by reading the test code.
The advantage of BDD is that the same semantics can also be used for user stories and acceptance criteria. Therefore acting as a bridge between specification and code.
35)Difference between class and module?
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║ ║ class ║ module ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated ║ can *not* be instantiated ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage ║ object creation ║ mixin facility. provide ║
║ ║ ║ a namespace. ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass ║ module ║ object ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ consists of ║ methods, constants, ║ methods, constants, ║
║ ║ and variables ║ and classes ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods ║ class methods, ║ module methods, ║
║ ║ instance methods ║ instance methods ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance ║ inherits behavior and can ║ No inheritance ║
║ ║ be base for inheritance ║ ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion ║ cannot be included ║ can be included in classes and ║
║ ║ ║ modules by using the include ║
║ ║ ║ command (includes all ║
║ ║ ║ instance methods as instance ║
║ ║ ║ methods in class/module) ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension ║ can not extend with ║ module can extend instance by ║
║ ║ extend command ║ using extend command (extends ║
║ ║ (only with inheritance) ║ given instance with singleton ║
║ ║ ║ methods from module) ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝
36)What is the activerecord?
Ans:ActiveRecord provides an object-oriented interface to an application's database to make development easier and friendlier for the developer. It provides validation functionality as well which helps keep data in the database clean. ActiveRecord also pertains to the model part of the MVC(Model)
37)What is the rake?and use of rake?
Ans:rake is ruby standlone command.It used to run the list of tasks.like rake db:migrate
38)What is the use of seeds in rails?
Ans: Rails gods have given us a way of feeding default values easily and quickly to a fresh installation. This is a normal Ruby program within the Rails environment. You have full access to all classes and methods of your application.
So you do not need to enter everything manually with rails console in order to make the records created in the section called “create” available in a new Rails application, but you can simply use the following file db/seeds.rb:
rake db:seed
39)What is the difference between application server and webserver?
Ans:apache, nginx, IIS are web servers
mongrel, webrick, phusion passenger are app servers
App server is something which works with particular programming language and parses and executes the code
since mongrel and webrick can only work with rails, so they are app servers
Web servers are servers which can take the request from the browser.
Web servers normally works on port 80 though we can change the port in configuration
since mongrel and webrick can take that request directly, so they can be thought of as web servers but web servers do have a lot of other functionality like request pipeline, load balancing etc.
App servers lack these functionalities.
About Mongrel server:
mongrel work as web as well as app server if you are talking about dev environment
but in production, mongrel alone can not work it will be too slow
so we need a web server in front of mongrel
40)Write the search dropdown in jquery?
41)What is the use of factorygirl in rails?
42)Hash with get maximun key and value in rails?
Ans:a = {"koti" => 95,"sam" => 99,"raghu" => 101,"raa" => 1}
a.max_by{|k,v| v}
=> ["raghu", 101]
43)Difference between rails2 and rails3?
Ans:
(1) Introduction of bundler (New way to manage your gem dependencies) *
(2) Gemfile and Gemfile.lock (Where all your gem dependencies lies, instead of environment.rb) *
(3) A new .rb file in config/ folder, named as application.rb
(Which has everything that previously environment.rb had) *
(4) Change in SQL Structure: Model.where(:activated => true) *
(5) All the mailer script will now be in app/mailers folder,
earlier we kept inside app/models. *
(6) Rails3-UJS support. for links and forms to work as AJAX,
instead of writing complex lines of code, we write :remote => true *
(7) HTML 5 support. *
(8) Changes in the model based validation syntax: validates :name, :presence => true *
(9) Ability to install windows/ruby/jruby/development/production specific gems to Gemfile.
group :production do
gem 'will_paginate'
end
44)Diffrerence between ruby1.9.3 and ruby2.0.0?
45)Difference between rails3 and rails4?
Ans:1. Ruby Versions
2. ‘Gemfile’
3. ‘Threadsafe’ by Default
4. No More vendor/plugins
5. New Testing Directories
6. Strong Parameters
7. Renamed Callback
10. Queuing system
13. Cache Digests (Russian Doll Caching)
14. Turbolinks
46)What is default scope in rails?
Ans:Scope is class method.retrieving and querying objects.
default_scope -> When ever active record is loaded that time only load default.
scope -> It will load when we call the scope method
class Post < ActiveRecord::Base
scope :published, where(status: 'published')
scope :draft, -> { where(status: 'draft') }
end
The main difference between both usages is that the :published condition is evaluated when the class is first loaded, whereas the :draft one is lazy evaluated when it is called. Because of that, in Rails 4 the first way is going to be deprecated which means you will always need to declare scopes with a callable object as argument. This is to avoid issues when trying to declare a scope with some sort of Time argument:
47)What is function of garbage collection in Ruby on Rails?
Ans:The Ruby runtime has a garbage collector. Depending on the runtime (JRuby/JVM generational GC, IronRuby/CLR generational GC, classic Ruby/mark-sweep GC) different algorithms are used. But the basics are pretty simple.
Garbage collection allows the removal of the pointer values that is left behind when the execution of the program ends.
-It frees the programmer from tracking the object that is being created dynamically on runtime.
-It provides a provision to remove the inaccessible objects from the memory and frees it so that other processes can use it.
-Garbage collection is used as:
x = Object.new
# this object is in use and it is residing in the memory. If it is not used then the status says
x = nil
# this means that the object can be removed from the memory and the memory can be freed for the other processes to run.
48)What is difference between render and redirect?
Ans:Redirect is used to tell the browser to issue a new request. Whereas, render only works in case the controller is being set up properly with the variables that needs to be rendered
49)What is orm?
Ans:ORM means object relational mapping.classes are directly mapped to tables,objects are mapped to rows and object attributes mapped to columns.
50)what is convention overconfiguration in rails?
51)How to define class?
52)What is REST in rails?
Ans:REpresentational State Transfer and describes resources (in our case URLs) on which we can perform actions. CRUD, which stands for Create, Read, Update, Delete, are the actions that we perform. Although, in Rails, REST and CRUD are bestest buddies, the two can work fine on their own. In fact, every time you have written a backend system that allows you to add, edit and delete items from the database, and a frontend that allows you to view those items, you have been working with CRUD
53)What is Ruby Gems?
Ans:- A gem is nothing more than a piece of ruby code packaged as a library so that it can be imported and used by others in their programs.
- A Ruby gem is therefore simply a library that is written in the ruby programming language.
54)What is Gemfile and Gemfile.lock?
Ans:The Gemfile is where you specify which gems you want to use, and lets you specify which versions. The Gemfile.lock file is where Bundler records the exact versions that were installed. This way, when the same library/project is loaded on another machine, running bundle install will look at the Gemfile.lock and install the exact same versions, rather than just using the Gemfile and installing the most recent versions. (Running different versions on different machines could lead to broken tests, etc.) You shouldn’t ever have to directly edit the lock file.
55)Ruby support multipleinheritance ? How can we implement?
Ans:
56)What is layouts?
Ans:Layouts are partial ruby/html files that are used to render the content pages.
There are placed in the folder: app/views/layouts
Items that you would typically put in this folder are things like headers/footers, navigation elements, etc.
57)What is the purpose of yield?
Ans:
58)What is observers and how can we will implement observers in rails?
Ans:
59)What is the ploymorphic associations? explain?
Ans:
60)What is minitest?
Ans:
61)What is unit testing?
Ans:
62)What is functional testing?
Ans:
63)What is integration testing?
Ans:
64)What are the joins in mysql and explain?
Ans:
65)What is the agile methodology?
Ans:
66)Difference between symbol and string?
Ans:
67)What is the request.xhr?
Ans:
68)How to Upload the images in rails?
Ans:
69)What is thread-safe?
Ans:
70)What is the thread?
Ans:
71)What is the difference between nil and false in ruby?
Ans:
72)What is the difference between git and github?
Ans:
73)What is the svn?
Ans:
74)How to change the one column all records change the uppercase in mysql?
Ans:
75)How Can We Make A Rails App Faster?
Ans:There are three ways to make your app faster: scaling, caching, and code optimization.
Scaling is easy these days. Heroku basically does it for you, and Hirefire makes the process automatic. You can learn more about autoscaling here. Other hosted environments offer similar solutions. By all means, use them if you can. But keep in mind that scaling is not a silver performance bullet. If your app serves the single request in 5 minutes, no amount of scaling will help. Also, with Heroku + Hirefire it's almost too easy to break the bank. I've seen Hirefire scaling up one of my apps to 36 dynos and having me to pay a whopping $3100 for that. Sure thing, I went ahead, scaled down manually to 2 dynos, and optimized the code instead.
Rails caching is also easy to do. Rails fragment caching is very good in Rails 4. Rails docs is an excellent source of info on caching. Another good read is Cheyne Wallace's article on Rails performance. It's also easy to setup Memcached these days. But as with scaling, caching is not an ultimate solution to performance problems. If your code is not working optimally, then you'll find yourself spending more and more resources on caching, to the point when caching stops making things faster.
The only reliable way to make your Rails app faster is code optimization. In Rails' case it's memory optimization. And, of course, if you follow my advice and avoid Rails to do things it's not designed for, you'll have even less code to optimize.
Let me tell you how to optimize your Rails app in 7 simple steps.
2.1 Avoid Memory Intensive Rails Features
Some features in Rails take more memory than necessary resulting in extra garbage collection runs. Here's the list.
2.1.1 Serializers
Serializer is a convenient way to represent strings from the database in a Ruby data type.
class Smth < ActiveRecord::Base
serialize :data, JSON
end
Smth.find(...).data
Smth.find(...).data = { ... }
But convenience comes with 3x memory overhead. If you store 100M in data column, expect to allocate 300M just to read it from the database.
Like learning from posts like this? Subscribe for more!
It's more memory efficient to do the serialization yourself like this:
class Smth < ActiveRecord::Base
def data
JSON.parse(read_attribute(:data))
end
def data=(value)
write_attribute(:data, value.to_json)
end
end
Like learning from posts like this? Subscribe for more!
This will have only 2x memory overhead. Some people, including myself, have seen Rails' JSON serializers leak memory, about 10% of data size per request. I do not understand the reason behind this. Neither do I have a reproducible case. If you experienced that, or know how to reproduce the leak, please let me know.
2.1.2 Active Record
It's easy to manipulate the data with ActiveRecord. But ActiveRecord is essentially a wrapper on top of your data. If you have a 1G of data in the table, ActiveRecord representation of it will take 2G and, in some cases, more. Yes, in 90% of cases that overhead is justified by extra convenience that you get. But sometimes you don't need it.
One example where you can avoid ActiveRecord's overhead is bulk updates. The code below will neither instantiate any model nor run validations and callbacks.
Book.where('title LIKE ?', '%Rails%').update_all(author: 'David')
Like learning from posts like this? Subscribe for more!
Behind the scenes it will just execute SQL UPDATE statement.
update books
set author = 'David'
where title LIKE '%Rails%'
Another example is iteration over a large dataset. Sometimes you need only the data. No typecasting, no updates. This snippet just runs the query and avoids ActiveRecord altogether:
result = ActiveRecord::Base.execute 'select * from books'
result.each do |row|
# do something with row.values_at('col1', 'col2')
end
Like learning from posts like this? Subscribe for more!
2.1.3 String Callbacks
Rails callbacks like before/after save, before/after action and so on are heavily used. But the way you write them may kill your performance. Here are the 3 ways you can write, for example, before_save callback:
before_save :update_status
before_save do |model|
model.update_status
end
before_save "self.update_status"
Like learning from posts like this? Subscribe for more!
First two ways are good to go, third is not. Why? Because to execute this callback Rails need to store execution context (variables, constants, global instances, etc.) that is present at the time of the callback. If your application is large, you end up copying a lot of data in the memory. Because callback can be executed any time, the memory cannot be reclaimed until your program finishes.
Having symbol callbacks saved me in one occasion 0.6 sec per request.
2.2 Write Less Ruby
This is my favorite step. As my university CS class professor liked to say, the best code is the one that doesn't exist. Sometimes the task at hand is better done with other tools. Most commonly it's a database. Why? Because Ruby is bad at processing large data sets. Like, very very bad. Remember, Ruby takes a large memory footprint. So, for example, to process 1G of data you might need 3G and more of memory. It will take several dozen seconds to garbage collect 3G. Good database can process the data in under a second. Let me show a few examples.
2.2.1 Attribute Preloading
Sometimes after denormalization attributes of the model get stored in another database table. For example, imagine we're building a TODO list that consists of task. Each task can be tagged with one or several tags. Denormalized data model will look like this:
Tasks
id
name
Tags
id
name
Tasks_Tags
tag_id
task_id
Like learning from posts like this? Subscribe for more!
To load tasks and their tags in Rails you would do this:
tasks = Task.find(:all, :include => :tags)
> 0.058 sec
Like learning from posts like this? Subscribe for more!
The problem with the code is that it creates an object for every Tag. That takes memory. Alternative solution is to do tag preloading in the database.
tasks = Task.select <<-END
*,
array(
select tags.name from tags inner join tasks_tags on (tags.id = tasks_tags.tag_id)
where tasks_tags.task_id=tasks.id
) as tag_names
END
> 0.018 sec
Like learning from posts like this? Subscribe for more!
This requires memory only to store an additional column that has an array of tags. No wonder it's 3x faster.
2.2.2 Data Aggregation
By data aggregation I mean any code that to summarizes or analyzes datasets. These operations can be simple sums, or anything more complex. Let's take group rank for example. Let's assume we have a dataset with employees, departments and salaries and we want to calculate the employee's rank within a department by salary.
SELECT * FROM empsalary;
depname | empno | salary
-----------+-------+-------
develop | 6 | 6000
develop | 7 | 4500
develop | 5 | 4200
personnel | 2 | 3900
personnel | 4 | 3500
sales | 1 | 5000
sales | 3 | 4800
Like learning from posts like this? Subscribe for more!
You can calculate the rank in Ruby:
salaries = Empsalary.all
salaries.sort_by! { |s| [s.depname, s.salary] }
key, counter = nil, nil
salaries.each do |s|
if s.depname != key
key, counter = s.depname, 0
end
counter += 1
s.rank = counter
end
Like learning from posts like this? Subscribe for more!
With 100k records in empsalary table this program finishes in 4.02 seconds. Alternative Postgres query using window functions does the same job more than 4 times faster in 1.1 seconds.
SELECT depname, empno, salary, rank()
OVER (PARTITION BY depname ORDER BY salary DESC)
FROM empsalary;
depname | empno | salary | rank
-----------+-------+--------+------
develop | 6 | 6000 | 1
develop | 7 | 4500 | 2
develop | 5 | 4200 | 3
personnel | 2 | 3900 | 1
personnel | 4 | 3500 | 2
sales | 1 | 5000 | 1
sales | 3 | 4800 | 2
Like learning from posts like this? Subscribe for more!
4x speedup is already impressive, but sometimes you get more, up to 20x. One example from my own experience. I had a 3-dimensional OLAP cube with 600k data rows. My program did slicing and aggregation. When done in Ruby, it took 1G of memory and finished in about 90 seconds. Equivalent SQL query finished in 5 seconds.
2.3 Fine-tune Unicorn
Chances are you are already using Unicorn. It's the fastest web server that you can use with Rails. But you can make it even faster.
2.3.1 App Preloading
Unicorn lets you preload your Rails application before forking worker processes. This has two advantages. First, with copy-on-write friendly GC (Ruby 2.0 and later) workers can share data loaded into memory by master process. That data will be transparently copied by an operating system in case worker changes it. Second, preloading reduces worker startup time. It's normal for Rails workers to be restarted (we'll talk about this in a moment), so the faster they restart, the better performance you get.
To turn on application preloading, simply include this line into your unicorn configuration file:
preload_app true
Like learning from posts like this? Subscribe for more!
2.3.2 GC Between Requests
Remember, GC amounts for up to 50% of your application runtime. That's not the only problem. GC is also unpredictable and happens exactly when you don't want it. What can we do about that?
First thing that comes to mind, what if we disable GC altogether? It turns out that's a bad idea. Your application can easily take 1G of memory before you notice. If you run several workers on your server, you will run out of memory even on a self-hosted hardware. Not to mention Heroku with its default 512M limit.
There's a better idea. If we cannot avoid GC, we can make it more predictable and run when there's nothing else to do. For example, between requests. It's actually easy to do this with Unicorn.
For Ruby < 2.1 there's OobGC Unicorn module:
require 'unicorn/oob_gc'
use(Unicorn::OobGC, 1) # "1" here means "force GC after every 1 request"
For Ruby >= 2.1 it's better to use [gctools](https://github.com/tmm1/gctools):
require 'gctools/oobgc'
use(GC::OOB::UnicornMiddleware)
Like learning from posts like this? Subscribe for more!
GC between requests has its caveats. Most importantly, this improves only perceived application performance. Meaning that the users will definitely see the optimization. You server hardware will actually have to do more work. Instead of doing GC as necessary, you will force your server to do it more often. So make sure you have enough resources to run GC and enough workers to serve incoming requests while other workers are busy with GC.
2.4 Limit Growth
I gave you several examples already where your application can grow up to 1G of memory. Taking a huge piece of memory by itself might not be a problem if you have a lot of memory. The real problem is that Ruby might not give that memory back to the operating system. Let me explain why.
Ruby allocates memory in two heaps. All Ruby objects go to Ruby's own heap. Each object has 40 bytes (on a 64-bit system) to store its data. When object needs to store more, it will allocate space in operating system's heap. When object is garbage collected and then freed, the space in the operating system's heap goes back to the operating system of course. But the space reserved for the object itself in Ruby heap is simply marked as free.
This means that Ruby heap can only grow. Imagine, you read 1 million rows, 10 columns in each row from the database. For that you allocate at least 10 million objects to store the data. Usually, Rails workers in average applications take 100M after start. To accommodate the data, the worker will grow by additional 400M (10 million objects, 40 bytes each). Even after you done with the data and garbage collect it, the worker will stay at 500M.
Disclaimer, Ruby GC does have the code to shrink the heap. I have yet to see that happen in reality because the conditions for heap to shrink rarely happen in production applications.
If your workers can only grow, the obvious solution is to restart the ones that get too big. Some hosting services, Heroku for example, do that for you. Let's see the other ways to do that.
2.4.1 Internal Memory Control
Trust in God, but lock your car. There're 2 types of memory limits your application can control on its own. I call them kind and hard.
Kind memory limit is the one that's enforced after each request. If worker is too big, it can quit and Unicorn master will start the new one. That's why I call it "kind", it doesn't abrupt your application.
To get the process memory size, use RSS metric on Linux and MacOS or OS gem on Windows. Let me show how to implement this limit in Unicorn configuration file:
class Unicorn::HttpServer
KIND_MEMORY_LIMIT_RSS = 150 #MB
alias process_client_orig process_client
undef_method :process_client
def process_client(client)
process_client_orig(client)
rss = `ps -o rss= -p #{Process.pid}`.chomp.to_i / 1024
exit if rss > KIND_MEMORY_LIMIT_RSS
end
end
Like learning from posts like this? Subscribe for more!
Hard memory limit is set by asking the operating system to kill your worker process if it grows too much. On Unix you can call setrlimit to set the RSS limit. To my knowledge, this only works on Linux. MacOS implementation was broken at some point. I'd appreciate any new information on that matter.
This the snippet from Unicorn configuration file with the hard limit:
after_fork do |server, worker|
worker.set_memory_limits
end
class Unicorn::Worker
HARD_MEMORY_LIMIT_RSS = 600 #MB
def set_memory_limits
Process.setrlimit(Process::RLIMIT_AS, HARD_MEMORY_LIMIT * 1024 * 1024)
end
end
Like learning from posts like this? Subscribe for more!
2.4.2 External Memory Control
Self-control does not save you from occasional OOM (out of memory). Usually you should setup some external tools. On Heroku there's no need as they have their own monitoring. But if you're self-hosting, it's a good idea to use monit, god, or any other monitoring solution.
2.5 Tune Ruby GC
In some cases you can tune Ruby GC to improve its performance. I'd say that these GC tuning is becoming less and less important, as the default settings in Ruby 2.1 and later are already good for most people.
To fine-tune GC you need to know how it works. This is a separate topic that does not belong to this article. To learn more, read a thorough Demystifying the Ruby GC article by Sam Saffron. In my upcoming Ruby Performance book I dig into even deeper details of Ruby GC. Subscribe here and I will send you email when I finish at least the beta version of the book.
My best advice is, probably, do not change GC settings unless you know what you are doing and have a good theory on how that can improve performance. This is especially true for Ruby 2.1 and later users.
I know only of one case when GC tuning helps. It's when you load large amounts of data in a single go. Here's when you can decrease the frequency of GC runs by changing the following environment variables: RUBY_GC_HEAP_GROWTH_FACTOR, RUBY_GC_MALLOC_LIMIT, RUBY_GC_MALLOC_LIMIT_MAX, RUBY_GC_OLDMALLOC_LIMIT, and RUBY_GC_OLDMALLOC_LIMIT.
Note, these are variables from Ruby 2.1 and later. Previous versions have less variables, and often use different names.
RUBY_GC_HEAP_GROWTH_FACTOR, default value 1.8, controls how much the Ruby heap grows when there's not enough heap space to accommodate new allocations. When you work with large amounts of objects, you want your heap space grow faster. In this case, increase the heap growth factor.
Memory limits define how often GC is triggered when you allocate memory on operating system's heap. Default limit values in Ruby 2.1 and later are:
New generation malloc limit RUBY_GC_MALLOC_LIMIT 16M
Maximum new generation malloc limit RUBY_GC_MALLOC_LIMIT_MAX 32M
Old generation malloc limit RUBY_GC_OLDMALLOC_LIMIT 16M
Maximum old generation malloc limit RUBY_GC_OLDMALLOC_LIMIT_MAX 128M
Like learning from posts like this? Subscribe for more!
Let me briefly explain what these values mean. With the configuration as above, for every 16M to 32M allocated by new objects, and for every 16M to 128M allocated by old objects ("old" means that an object survived at least 1 garbage collection call) Ruby will run GC. Ruby dynamically adjust the current limit value depending on your memory allocation pattern .
So, if you have small number of objects that take large amounts of memory (for example, read large files into one string), you can increase the limits to trigger GC less often. Remember to increase all 4 limits, better proportionally to their default values.
My advice, however, differs from what other people recommend. What worked for me might not work for you. Here are the articles describing what worked for Twitter and for Discourse.
2.6 Profile
Sometimes none of the ready-to-use advice can help you, and you need to figure out what's wrong yourself. That's when you use the profiler. Ruby-Prof is what everybody uses in Ruby world.
To learn more on profiling, read Chris Heald's and my own articles on using ruby-prof with Rails. Later also has, albeit outdated, advice on memory profiling.
2.7 Write Performance Tests
The last, but by all means not the least important step in making Rails faster is to make sure that slowdowns do not happen again after you fix them. Rails 3.x has performance testing and profiling framework bundled in. For Rails 4 you can use the same framework extracted into rails-perftest gem.
3 Closing Thoughts
It's not possible to cover everything on Ruby and Rails performance optimization in one post. So lately I decided to summarize my knowledge in a book. If you find my advice helpful, please sign up for the mailinglist and I'll notify you once I have an early preview of this book ready. Now, go ahead, and make your Rails application faster!
"Great blog created by you. I read your blog, its best and useful information. You have done a great work. Super blogging and keep it up.php jobs in hyderabad.
ReplyDelete"
I like your post very much. It is very much useful for my research. I hope you to share more info about this. Keep posting ruby on rails online training hyderabad
ReplyDelete