ruby on rails interview questions

Praaveen Vr
praaveen
Published in
9 min readNov 19, 2019

It’s a mixed collection from other source and mine(I will be keep updating the blog)

1. meta-programming

Metaprogramming is writing code that writes code during runtime. As a dynamic language, Ruby gives you the freedom to define methods and even classes during runtime. Metaprogramming with Ruby, one can do in a few minutes what other languages may take hours to do

2. proc and lamda from

https://www.rubyguides.com/2016/02/ruby-procs-and-lambdas

A lambda is a way to define a block & its parameters with some special syntax. You can save this lambda into a variable for later use

my_block = -> { puts "sample lambda code" } 
my_block.call
multiple_block = ->(x) { x * 2 }
multiple_block.call(10)
# 20

Proc

Procs are a very similar concept. One of the differences is how you create them. Another difference between procs & lambdas is how they react to a return statement.

def call_proc
puts “Before proc”
my_proc = Proc.new { return 2 }
my_proc.call
puts “After proc”
end
> p call_procoutput :
Before proc
2
def call_lambda
puts "Before lambda"
my_lambda = -> { return 1 }
my_lambda.call
puts "After lambda"
end
> p call_lambda
Before proc
After proc
nil

A lambda will return normally, like a regular method. But a proc will try to return from the current context.

Here is a summary of how procs and lambdas are different:

  • Lambdas are defined with -> {} and procs with Proc.new {}.
  • Procs return from the current method, while lambdas return from the lambda itself.
  • Procs don’t care about the correct number of arguments, while lambdas will raise an exception.

Taking a look at this list, we can see that lambdas are a lot closer to a regular method than procs are.

3. ruby is dynamic typed language / duck typing

Statically typed languages, This means that when you associate a variable to a type then you cannot change it anymore.
In C

int main(){  
int x;
x = "rubycademy.com"; // warning: incompatible pointer to integer conversion assigning to 'int' from 'char [15]' [-Wint-conversion]
return (0);}

Note that statically typed languages are generally compiled language, as the compiler can type-check each variable through multiple defined constraints at compile time.

Dynamically typed languages, This means that when you associate a variable to a type then you can change it whenever you want.

Actually, typing is associated with the value it assumes rather than the variable itself.

a = 'test'
a.class #String
a = true
a.class #TrueClass

So the type is defined at runtime

4. N+1 queries

pry(main)> ur = UserRole.last(2)UserRole Load (1.0ms)  SELECT  "user_roles".* FROM "user_roles"   ORDER BY "user_roles"."id" DESC LIMIT 2=> [#<UserRole id: 736, user_id: 478, role_id: 4, created_at: "2019-03-20 08:03:42", updated_at: "2019-03-20 08:03:42">,#<UserRole id: 737, user_id: 478, role_id: 5, created_at: "2019-03-20 08:03:42", updated_at: "2019-03-20 08:03:42">]pry(main)> ur.first.userUser Load (1.3ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = $1 LIMIT 1  [["id", 478]]=> #<User id: 478, first_name: "ganga", last_name: "df", email: "praaveen.vr+ganga@spritle.com", tenant_id: 190, created_at: "2019-03-20 08:03:41", updated_at: "2019-03-20 08:05:48", encrypted...

The above code works, but it makes far too many independent database queries. For example in order get the user of last two user role, above code will have 3 queries.

Eager Loading in Rails

pry(main)> ur = UserRole.includes(:user).last(2)

UserRole Load (0.6ms) SELECT "user_roles".* FROM "user_roles" ORDER BY "user_roles"."id" DESC LIMIT 2
User Load (1.1ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (478)
=> [#<UserRole id: 736, user_id: 478, role_id: 4, created_at: "2019-03-20 08:03:42", updated_at: "2019-03-20 08:03:42">,
#<UserRole id: 737, user_id: 478, role_id: 5, created_at: "2019-03-20 08:03:42", updated_at: "2019-03-20 08:03:42">]
pry(main)> ur.first.user=> #<User id: 478, first_name: "ganga", last_name: "df", email: "praaveen.vr+ganga@spritle.com", tenant_id: 190, created_at: "2019-03-20 08:03:41", updated_at: "2019-03-20 08:05:48" ....>

but with includes(:user) only 2 queries.

Event if you request for 100 records with include it will be only 2 query but with out include will make 100 +1 queries

5. delegate

delegate provides a delegate class method to easily expose contained objects’ public methods as your own. Simply say, through delegation you can use public methods in other model directly.

6.Difference between include and extend

Instead of including the module, you can (less commonly) also extendit. The difference is that including the module makes all the module's methods instance methods whereas extending the module makes all its methods class methods (e.g. as if it prepended each one of them with self.).

include is used bringing all the methods of a module into the class as instance methods. These are mixinsused in Ruby as it does not support Multiple inheritance.

An Example

You can see both of these in action below:

module ModuleExample
def foo
'foo'
end
end
# Including modules binds the methods to the object instance
class Person
include ModuleExample
end
# Extending modules binds the methods to the class itself
class Book
extend ModuleExample
end
# IRB
> Person.foo
# => NoMethodError: undefined method `foo' for Person:Class
> Person.new.foo
# => 'foo'
> Book.foo
# => 'foo'
> Book.new.foo
# => NoMethodError: undefined method `foo'

7. Difference between Load and require

First of all, include and extend are language-level methods where as require and load are file-level methods. But all methods are used to support DRY concept of Ruby.

8. callbacks

Filters: Filters are methods that are run before, after or “around” a controller action

Callbacks: Callbacks allow you to trigger logic before or after an alteration of an object’s state in model.

9. Explain what is ORM in rails ?

ORM stands for Object-Relational-Mapping. It basically means that Active Record takes data which is stored in a database table using rows and columns, which needs to be modified or retrieved by writing SQL statements (if you’re using a SQL database), and it lets you interact with that data as though it was a normal Ruby object.

Example: Suppose you want to fetch an array of all the users then instead of writing any code for database connection and then writing some SQL query like SELECT * FROM users and converting the result into an array, I can just type User.all and Active Record gives me that array filled with User objects that I can play with as I'd like.

It doesn’t really matter which type of database you’re using. Active Record smooths out all the differences between those databases for you so you don’t have to think about it. You focus on writing code for your application, and Active Record will think about the nitty gritty details of connecting you to your database. It also means that if you switch from one database to another, you don’t actually need to change any major application code, just some configuration files.

10. databases indexes

If you are looking to increase the performance of your data driven web application, the answer may be as simple as adding an index to the correct column of your database table.

A database index is exactly what it sounds like. If you think of the index at the back of a reference book: a quickly searchable list of pointers to get to the actual data. Without an index, a database query might have to look at every row in your database table to find the correct result.
For more details refer the link.

11. About stackoverflow contribution?

online community for anyone that codes to learn, share their knowledge, and build their careers.

12. About version controller(eg: git) ?

https://git-scm.com

Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.

13. github repos and contributions?

14.Active Record Associations

  • belongs_to
  • has_one
  • has_many
  • has_many :through
  • has_one :through
  • has_and_belongs_to_many

a. Choosing Between has_many :through and has_and_belongs_to_many

You should use has_many :through if you need validations, callbacks or extra attributes on the join model.

b. Choosing Between belongs_to and has_one
c. Polymorphic Associations

https://launchschool.com/blog/understanding-polymorphic-associations-in-rails

A slightly more advanced twist on associations is the polymorphic association. With polymorphic associations, a model can belong to more than one other model, on a single association. For example, you might have a picture model that belongs to either an employee model or a product model. Here’s how this could be declared:

class Picture < ApplicationRecordbelongs_to :imageable, polymorphic: trueendclass Employee < ApplicationRecordhas_many :pictures, as: :imageableendclass Product < ApplicationRecordhas_many :pictures, as: :imageableend

d.Self Joins

https://medium.com/@TheDickWard/self-referential-relationships-aka-self-joins-in-rails-64f8f36ac311

In designing a data model, you will sometimes find a model that should have a relation to itself. For example, you may want to store all employees in a single database model, but be able to trace relationships such as between manager and subordinates. This situation can be modeled with self-joining associations:

class Employee < ApplicationRecord
has_many :subordinates, class_name: "Employee",
foreign_key: "manager_id"
belongs_to :manager, class_name: "Employee"
end

With this setup, you can retrieve @employee.subordinates and @employee.manager.

c. Single Table Inheritance

https://devblast.com/b/single-table-inheritance-with-rails-4-part-1

Sometimes, you may want to share fields and behavior between different models. Let’s say we have Car, Motorcycle and Bicycle models. We will want to share the color and price fields and some methods for all of them, but having some specific behavior for each, and separated controllers too

Compare STI and Polymorphic

https://www.freecodecamp.org/news/single-table-inheritance-vs-polymorphic-associations-in-rails-af3a07a204f2/

15. Explain Cross-Site Request Forgery (CSRF) and how Rails is protected against it?

CSRF is a form of attack where hacker submits a page request on your behalf to a different website, causing damage or revealing your sensitive data. To protect from CSRF attacks, you have to add “protect_from_forgery” to your ApplicationController. This will cause Rails to require a CSRF token to process the request. CSRF token is given as a hidden field in every form created using Rails form builders.

16.Design patterns

Reference

https://www.sitepoint.com/7-design-patterns-to-refactor-mvc-components-in-rails/
https://naturaily.com/blog/ruby-on-rails-design-patterns

a. Service design pattern

b. Decorator design pattern

17. oauth2

18.Multi tenancy

https://medium.com/@praaveen/multi-tenancy-and-sub-domain-lvh-with-rails-f5167b550be6

a. act_as_tenant gem

b. appartment gem
Difference between these two gems

19.Monkey patching

Reference : https://culttt.com/2015/06/17/what-is-monkey-patching-in-ruby/

One of the most powerful aspects of Ruby is the ability to re-open any class and change it’s methods.

Yes that’s right, you can actually reopen any class and change how it works. This includes the standard Ruby classes like String, Array or Hash!

Now this is obviously as dangerous as it sounds. Being able to change the expected outcome of a method can cause all sorts of weird behaviour and difficult to track down bugs.

But nonetheless, the ability to “Monkey Patch” any class is extremely powerful. Ruby is like a sharp knife, it can be extremely effective, but it’s usually your own fault if you cut yourself.

20. Difference between each, map, collect

21. Dependency delete

22. index: true vs foreign_key: true (Rails)

23. About rake and rack

24. micro services

25. Application server

26. Web server in rails

27. About HTTP and HTTPS

28. Client Server communication(request and response)

29. Cookies, session

30. soft delete

31. websocket

32. rspec

33. Meta programming examples

34.Code refactor

35.ruby snippets for skill testing

36.Difference between find and find_by_id

37.Keep up to date in ruby and rails versions

38.Classes vs Modules

39. Any gem you have worked

40. Devise gem

41. database Queries

42. counter_cache
Instead of counting the associated records in the database every time the page loads, ActiveRecord’s counter caching feature allows storing the counter and updating it every time an associated object is created or removed.

--

--