Show Menu
Cheatography

ruby-interview-seniour Cheat Sheet by

ruby-interview-seniour

OOP short

Object Oriented Progra­mming
Encaps­ula­tion: Bundling data and methods that operate on it, restri­cting direct access.
Abstra­ction: Hiding complex details, presenting a simple interface.
Inheri­tance: Child classes can inherit methods and properties from parent classes.
Polymo­rphism: Allows using an object like its parent while mainta­ining its own unique behavior.

OOP

Encaps­ulation
private public methods
Abstra­ctions
user blindly
Inheri­tance
u can replace parent methods with child methods
Polymo­rphism
Polymo­rphism gives us a way to use an object exactly like its parent but keeping its own methods as they are

Method Access Control short

Public: Methods accessible by anyone.
Protected: Only accessible by the defining class and its subcla­sses.
Private: Only accessible by the current object; cannot be called with an explicit receiver.

Method Access Control

Public methods can be called by everyone - no access control is enforced. A class's instance methods (these do not belong only to one object; instead, every instance of the class can call them) are public by default; anyone can call them. The initialize method is always private.
Protected methods can be invoked only by objects of the defining class and its subcla­sses. Access is kept within the family. However, usage of protected is limited.
Private methods cannot be called with an explicit receiver - the receiver is always self. This means that private methods can be called only in the context of the current object; you cannot invoke another object's private methods.

ActiveJob

emails
image processing
external API call
analytics calcul­ations

Rails Enige

Rails::Engine allows you to wrap a specific Rails application or subset of functionality and share it with other applications or within a larger packaged application. Every Rails::Application is just an engine, which allows for simple feature and application sharing.

Any Rails::Engine is also a Rails::Railtie, so the same methods (like rake_tasks and generators) and configuration options that are available in railties can also be used in engines.

# lib/my_engine.rb
module MyEngine
  class Engine < Rails::Engine
  end
end

RESTful

INDEX
GET users
NEW
GET users/new
SHOW
GET users/1
EDIT
GET users/­1/edit
UPDATE
PUT/PATCH users/1
DELETE
GET users/­1/d­elete
DESTROY
DELETE users/1
CREAET
POST users

How should you test routes

# Asserts that the default action is generated for a route with no action
assert_generates "/items", controller: "items", action: "index"

# Tests that the list action is properly routed
assert_generates "/items/list", controller: "items", action: "list"

# Tests the generation of a route with a parameter
assert_generates "/items/list/1", { controller: "items", action: "list", id: "1" }

# Asserts that the generated route gives us our custom route
assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" }

# Asserts that POSTing to /items will call the create action on ItemsController
assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post})

Active Record short

ORM: Maps objects to database tables, providing methods to represent models, relati­ons­hips, and valida­tions.
Associ­ations: Defines relati­onships like has_many, belong­s_to, and has_many :through.
Conven­tions: Naming conven­tions for tables and associ­ations, e.g., User has many Posts.

Active­Record

Active Record is the M in MVC - the model - which is the layer of the system respon­sible for repres­enting business data and logic. Active Record facili­tates the creation and use of business objects whose data requires persistent storage to a database. It is an implem­ent­ation of the Active Record pattern which itself is a descri­ption of an Object Relational Mapping system.

In Active Record, objects carry both persistent data and behavior which operates on that data. Active Record takes the opinion that ensuring data access logic as part of the object will educate users of that object on how to write to and read from the database.

Active Record gives us several mechan­isms, the most important being the ability to:

Represent models and their data.
Represent associ­ations between these models.
Represent inheri­tance hierar­chies through related models.
Validate models before they get persisted to the database.
Perform database operations in an object­-or­iented fashion.

Object Relational Mapping

Object Relational Mapping, commonly referred to as its abbrev­iation ORM, is a technique that connects the rich objects of an applic­ation to tables in a relational database management system. Using ORM, the properties and relati­onships of the objects in an applic­ation can be easily stored and retrieved from a database without writing SQL statements directly and with less overall database access code.

Active Record conven­tions

user has_many
posts
Article
articles
PostCo­mment
post_c­omments
Mouse
mice
post belongs_to
user

Fat contro­llers

retrieving data from the model, transf­orming it as approp­riate for the view, and then passing it to the view for rendering

Refactor of models

If some code does work from the point of view of an Active­Record model, it can go into the model.

If some code does work that spans multiple tables­/ob­jects, and doesn’t really have a clear owner, it could go into a Service Object.

Anything that’s attrib­ute­-like (like attributes calculated from associ­ations or other attrib­utes) should go into your Active­Record model.

If you have logic that has to orches­trate the saving or updating of multiple models at once, it should go into an Active­Model Form Object.

If code is mostly meant for displaying or formatting models in a view, it should go into a Rails helper or a Presenter.

E-Tags short

Defini­tion: Response headers that identify a resource version, aiding in caching and content valida­tion.
Usage: If-Non­e-Match header checks if a resource has changed, allowing "304 Not Modifi­ed" responses.

E-tags

Defini­tion: An E-tag is a response header used to identify a specific version of a resource on a server. It's often a unique identi­fier, such as a hash or a version number, that changes whenever the resource changes.
Caching: E-tags are crucial for caching mechan­isms. When a client requests a resource, it receives an E-tag with the response. On subsequent requests, the client can send this E-tag back to the server with an "­If-­Non­e-M­atc­h" header, allowing the server to determine if the resource has changed. If it hasn't, the server can respond with a "304 Not Modifi­ed" status, reducing bandwidth usage by skipping the resource transfer.
Content Valida­tion: E-tags also help ensure content integrity. By comparing E-tags, clients and servers can verify that they are accessing the correct version of a resource, ensuring consis­tency between versions.
Implem­ent­ation: In practice, E-tags are generated and managed by the server. Developers might create custom logic to generate these tags or rely on server frameworks that handle them automa­tic­ally.
E-tags are partic­ularly useful in: Web APIs: For API responses, E-tags help reduce data transfer and ensure clients receive the latest inform­ation. Static Content: For web pages, CSS files, and JavaScript assets, E-tags prevent redundant downloads, speeding up page loads.
 

SOLID short

Single Respon­sib­ility: A class should handle one respon­sib­ility.
Open/C­losed: Classes should be open for extension but closed for modifi­cation.
Liskov Substi­tution: Subtypes should be substi­tutable for their parent types.
Interface Segreg­ation: Clients shouldn't depend on unused interf­aces.
Dependency Inversion: High-level modules should depend on abstra­ctions, not low-level modules.

SOLID

Single Respon­sib­ility Principle: A class should have only one reason to change, meaning it should handle a single respon­sib­ility or functi­ona­lity. This helps create modular code that's easier to understand and maintain.
Open/C­losed Principle: Software entities (such as classes or functions) should be open for extension but closed for modifi­cation. This means you should be able to add new functi­onality without altering existing code, typically through inheri­tance or compos­ition.
Liskov Substi­tution Principle: Subtypes should be substi­tutable for their base types. In other words, derived classes should be able to replace their parent classes without affecting the functi­onality of the applic­ation.
Interface Segreg­ation Principle: Clients should not be forced to depend on interfaces they do not use. This encourages the creation of small, specific interf­aces, rather than large, general ones, making the design more flexible and reducing coupling.
Dependency Inversion Principle: High-level modules should not depend on low-level modules; both should depend on abstra­ctions. This means code should rely on abstract interfaces rather than concrete implem­ent­ations, promoting decoupling and making the system easier to extend and maintain.

self

The keyword self in Ruby gives you access to the current object – the object that is receiving the current message. To explain: a method call in Ruby is actually the sending of a message to a receiver

Ruby method lookup path

user
User
Parent­::User
Object

Ruby callbacks

Create
Update
before­_save; before­_va­lid­ation
after_­update; after_­commit
Destroying
Touch
around­_de­stroy; after_­rol­lback
after_­ini­tia­lize; after_find

Proc and lambda

Lambda
Proc
Proc class (lambda)
Proc class
checks the number of arguments passed to it
proc does not
lambda returns, it passes control back to the calling method
proc returns, it does so immedi­ately, without going back to the calling method

Asset Pipeline

The asset pipeline provides a framework to concat­enate and minify or
compress JavaScript and CSS assets. It also adds the ability to write these assets
in other languages and pre-pr­oce­ssors such as Coffee­Script, Sass, and ERB

Caching short

Page Caching: Caches entire pages directly to disk.
Action Caching: Similar to page caching but runs before filters.
Fragment Caching: Caches parts of views separa­tely.
Low-Level Caching: Allows caching values or query results, reducing database load.

Caching 1/2

Page caching is a Rails mechanism which allows the request for a generated page to be fulfilled by the web server (i.e. Apache or NGINX) without having to go through the entire Rails stack. While this is super fast it can't be applied to every situation (such as pages that need authen­tic­ation). Also, because the web server is serving a file directly from the filesystem you will need to implement cache expira­tion.
Page Caching cannot be used for actions that have before filters - for example, pages that require authen­tic­ation. This is where Action Caching comes in. Action Caching works like Page Caching except the incoming web request hits the Rails stack so that before filters can be run on it before the cache is served. This allows authen­tic­ation and other restri­ctions to be run while still serving the result of the output from a cached copy.
Dynamic web applic­ations usually build pages with a variety of components not all of which have the same caching charac­ter­istics. When different parts of the page need to be cached and expired separately you can use Fragment Caching. Fragment Caching allows a fragment of view logic to be wrapped in a cache block and served out of the cache store when the next request comes in.

Caching 2/2

Low-level
SQL caching
Sometimes you need to cache a particular value or query result instead of caching view fragments. Rails' caching mechanism works great for storing any kind of inform­ation.
Query caching is a Rails feature that caches the result set returned by each query. If Rails encounters the same query again for that request, it will use the cached result set as opposed to running the query against the database again.
Rails.c­ac­he.f­et­ch(­"­#{c­ach­e_k­ey_­wit­h_v­ers­ion­}/c­omp­eti­ng_­pri­ce", expire­s_in: 12.hours) do Compet­ito­r::­API.fi­nd_­pri­ce(id) end
User.f­irst; User.first

Migrations

Rails provides a set of rake tasks to work with migrations which boil down to running certain sets of migrat­ions.

The very first migration related rake task you will use will probably be rake db:mig­rate. In its most basic form it just runs the up or change method for all the migrations that have not yet been run. If there are no such migrat­ions, it exits. It will run these migrations in order based on the date of the migration.

Note that running the db:migrate also invokes the db:sch­ema­:dump task, which will update your db/sch­ema.rb file to match the structure of your database.

Associ­ations

belongs_to
has_one
has_many
has_many :through
has_one :through
has_an­d_b­elo­ngs­_to­_many

scopes

Scoping allows you to specify common­ly-used queries(it can be considered as a shortcut for long or most frequently used queries) which can be referenced as method calls on the associ­ation objects or models. With these scopes, you can use every method previously covered such as where, joins and includes. All scope methods will return an Active­Rec­ord­::R­elation object which will allow for further methods (such as other scopes) to be called on it.
 

Basic info

Class is the blueprint from which individual objects are created
class variables are shared between a class and all its subclasses
Objects are instances of the class.
class instance variables only belong to one specific class

Use a constr­uctor in Ruby

def initia­liz­e({­});end;

getter and setter methods in Ruby

attr_r­eader
attr_a­ccessor

Class and a module

Modules are collec­tions of methods and constants.
They cannot generate instances. Classes may generate instances (objects), and have per-in­stance state (instance variab­les).

everything is an object in Ruby

Every data type that we work with is a class and classes are objects. Even the Object class is an object. Strings, integers, floats, hashes, arrays, symbols, classes, modules, errors and more are all objects.

Rack

Rack is the underlying technology behind nearly all of the web frameworks in the Ruby world.
"­Rac­k" is actually a few different things:
An archit­ecture - Rack defines a very simple interface, and any code that conforms
to this interface can be used in a Rack applic­ation. This makes it very easy to build small,
focused, and reusable bits of code and then use Rack to compose these bits into a larger applic­ation.

A Ruby gem - Rack is is distri­buted as a Ruby gem that provides the glue code needed to compose our code.

require "­rac­k"
require "­thi­n"

class HelloWorld
def call(env)
[ 200, { "­Con­ten­t-T­ype­" => "­tex­t/p­lai­n" }, ["Hello World"] ]
end
end

Rack::­Han­dle­r::­Thi­n.run HelloW­orl­d.new
https:­//g­ith­ub.c­om­/su­nli­ght­lab­s/r­ack­-ho­neypot

Rack defines a very simple interface. Rack compliant code must have the following three charac­ter­istics:

It must respond to call
The call method must accept a single argument -
This argument is typically called env or enviro­nment, and it bundles all of the data about the request.
The call method must return an array of three elements These elements are, in order,
status for the HTTP status code, headers, and body for the actual content of the response.
A nice side effect of the call interface is that procs and lambdas can be used as Rack objects.

Middleware are the building blocks of larger applic­ations built using the Rack pattern.
Each middleware is a Rack compatible applic­ation, and our final applic­ation is built by composing together, or nesting these middle­ware.

Unlike base Rack apps, middleware must be classes as they need to have an initia­lizer which will be passed the next app in the chain.
For our first middleware example, we'll introduce a middleware that logs the amount of time the request took and adds that to the response.

To begin, we'll update our core Rack app to sleep for 3 seconds to give us something worth logging, and then we'll build our middle­ware:
Rack::­Han­dle­r::­Thi­n.run Loggin­gMi­ddl­ewa­re.n­ew­(app)

Middleware are perfect for non-app specific logic.
Things like setting caching headers, logging, parsing the request object, etc. all are great use cases for Rack middle­ware.
For example, in Rails, cookie parsing, sessions, and param parsing are all handled by Middle­ware.

Rack Middleware

require "rack"
require "thin"

app = -> (env) do
  sleep 3
  [ 200, { "Content-Type" => "text/plain" }, ["Hello World\n"] ]
end

class LoggingMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    before = Time.now.to_i
    status, headers, body = @app.call(env)
    after = Time.now.to_i
    log_message = "App took #{after - before} seconds."

    [status, headers, body << log_message]
  end
end

Rack::Handler::Thin.run LoggingMiddleware.new(app)

optimistic pessim­istic locking

Optimistic
Pessim­istic
Optimistic locking is a mechanism to prevent data overrides by assuming that a database transa­ction conflict rarely happens
When one user is editing a record and we maintain an exclusive lock on that record, another user is prevented from modifying this record until the lock is released or the transa­ction is completed. This explicit locking is known as a pessim­istic lock
uses a "­ver­sio­n-n­umb­er" column to track changes in each table that needs to implement concurrent access
Optimistic locking is just a mechanism to prevent processes from overwr­iting changes by another process. Optimistic locking is not a magic wand to manage or auto-merge any confli­cting changes. It can only allow users to alert or notify about such confli­cting changes.
Optimistic locking works by just comparing the value of the "­ver­sio­n" column. Thus, optimistic locking is not a real database lock
multiple users can read the same resource at the same time but if more then one tries to modify the database , then we prevent it
multiple users will not be able to read while others are reading
Advisory Lock
An advisory lock is a voluntary locking mechanism that requires transa­ctions to explicitly request and release locks on resources. How it works: Transa­ctions explicitly acquire advisory locks on resources, signaling to other transa­ctions that they should also respect these locks. Advisory locks don't inherently block transa­ctions; instead, they rely on voluntary adherence. Use cases: Advisory locks are useful in systems where developers want fine-g­rained control over concur­rency or when specific business logic dictates locking behavior, such as file management systems.

postgres indexes

B-tree Index: Default type, suitable for equality (=) and range queries (<, >, BETWEEN).
Hash Index: Optimized for equality compar­isons (=).
GIN Index: Useful for indexing array, JSONB, and full-text search fields.
GiST Index: Flexible structure for complex data types, including geometric and range queries.
Partial Index: create index where condition
The order of columns in a multi-­column index affects how well it optimizes queries. Consider these factors: Query Patterns: Place the column most frequently used in queries or filters first. This increases the chances of the index being utilized effect­ively. Selective Columns: Columns with high select­ivity (i.e., a wide range of unique values) should appear first. This maximizes the potential for early filtering. Combining Columns: If queries often filter by a combin­ation of columns, ensure the index order matches the most common query patterns.
Highiest cardin­ality means better index. Columns with high cardin­ality have many unique values relative to the total number of rows.
 

singleton methods, Eigenclass

In Ruby, a class is an object. Indeed, a class is literally an instance of the class Class The eigenclass is an unnamed instance of the class Class attached to an object and which instance methods are used as singleton methods of the defined object.

RubyGems

The RubyGems software allows you to easily download, install, and use ruby software packages on your system.
The software package is called a “gem” which contains a packaged Ruby applic­ation or library.

Eigenclass

An eigenclass is a unique, anonymous class associated with an individual object in Ruby. It allows for the addition of methods directly to that object, without affecting other instances of its class.
Every Ruby object has an associated eigenc­lass, which is created automa­tically the first time a singleton method (a method defined only for that specific object) is added to it. The eigenclass stores these singleton methods.
Eigenc­lasses can be useful in Rails for extending or modifying specific instances of classes without affecting the class as a whole: Singleton Methods: You might use a singleton method to add behavior directly to an individual object, such as a single instance of a model, without altering its class defini­tion. Meta-P­rog­ram­ming: Eigenc­lasses play a role in meta-p­rog­ramming techni­ques, allowing for dynamic modifi­cations to objects.
class User < Applic­ati­onR­ecord end user = User.f­ind(1) def user.greet "­Hello, #{self.na­me}­!" end puts user.greet # Outputs "­Hello, [User's name]!­"

build your own Ruby gem

.gemspec
lib/mygem
gem build .gemspec
Use the basic lib/gem.rb and lib/gem/ structure for code.
Put any execut­ables in bin, any data files in data and tests in test or spec.
Don't require or depend upon files outside of the load path. (VERSION files often seem to live in odd places in gems.)
Do not require 'rubyg­ems'.
Do not tamper with the $LOAD_­PATH.

Favourites gems

rspec
cancancan
Active­Mod­elS­eri­alizers
capistrano
sidekiq
annotate

Filters in contro­llers

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

Strong params

Strong Parameters is a feature of Rails that prevents assigning request parameters to objects unless they have been explicitly permitted. It has its own DSL (Domain Specific Language, or in other words, a predefined syntax it unders­tands), that allows you to indicate what parameters should be allowed. It also lets you indicate if each parameter should be a hash, array or scalar (i.e. integer, string, etc.), as well as some other functi­onality

Controller specs

Send http requests to applic­ation and writing assertions about the response.

yield, conten­t_for

They are opposite ends of the rendering process, with yield specifying where content goes, and conten­t_for specifying what the actual content is.

The best practice is to use yield in your layouts, and conten­t_for in your views. There is a special second use for conten­t_for, where you give it no block and it returns the previously rendered content. This is primarily for use in helper methods where yield cannot work. Within your views, the best practice is to stick to yield :my_co­ntent to recall the content, and conten­t_for :my_co­ntent do...end to render the content.

nested layouts

This is a live content block, but has not yet been populated. Please check back soon.

Security

Content Security Policy
xss inj
sql inj
use ssl
session hijacking
reset_­session (expire)
session fixation

Password

Iterate over an HMAC with a random salt for about a 100ms duration and save the salt with the hash. Use functions such as passwo­rd_­hash, PBKDF2, Bcrypt and similar functions.

https (ssl)

HTTPS protects the commun­ication between your browser and server from being interc­epted and tampered with by attackers. This provides confid­ent­iality, integrity and authen­tic­ation to the vast majority of today's WWW traffic. Any website that shows a lock icon in the address bar is using HTTPS

Unit testing

In computer progra­mming, unit testing is a software testing method by which individual units of source code—sets of one or more computer program modules together with associated control data, usage proced­ures, and operating proced­ure­s—are tested to determine whether they are fit for use

Patterns

Creational
Structural
Behaviour
Abstract Factory is a creational design pattern that lets you produce families of related objects without specifying their concrete classes.
Adapter is a structural design pattern that allows objects with incomp­atible interfaces to collab­orate.
Observer is a behavioral design pattern that lets you define a subscr­iption mechanism to notify multiple objects about any events that happen to the object they’re observing.
Singletone
Decorator is a structural design pattern that lets you attach new behaviors to objects by placing these objects inside special wrapper objects that contain the behaviors.
Command is a behavioral design pattern that turns a request into a stand-­alone object that contains all inform­ation about the request. This transf­orm­ation lets you parame­terize methods with different requests, delay or queue a request’s execution, and support undoable operat­ions.
Prototype
Facade
Chain of respon­sib­ility
Factory Method is a creational design pattern that provides an interface for creating objects in a superc­lass, but allows subclasses to alter the type of objects that will be created.
Bridge is a structural design pattern that lets you split a large class or a set of closely related classes into two separate hierar­chi­es—­abs­tra­ction and implem­ent­ati­on—­which can be developed indepe­ndently of each other.

What is the primary technique for writing a test

Test actual result of execution, integr­ation tests, rather than only unit tests. Write scenario as a complex test

Eigenclass

An eigenclass is a unique, anonymous class associated with an individual object in Ruby. It allows for the addition of methods directly to that object, without affecting other instances of its class.
Every Ruby object has an associated eigenc­lass, which is created automa­tically the first time a singleton method (a method defined only for that specific object) is added to it. The eigenclass stores these singleton methods.
Eigenc­lasses can be useful in Rails for extending or modifying specific instances of classes without affecting the class as a whole: Singleton Methods: You might use a singleton method to add behavior directly to an individual object, such as a single instance of a model, without altering its class defini­tion. Meta-P­rog­ram­ming: Eigenc­lasses play a role in meta-p­rog­ramming techni­ques, allowing for dynamic modifi­cations to objects.
`
class User < Applic­ati­onR­ecord end user = User.f­ind(1) def user.greet "­Hello, #{self.na­me}­!" end puts user.greet # Outputs "­Hello, [User's name]!­"
`
       
 

Comments

No comments yet. Add yours below!

Add a Comment

Your Comment

Please enter your name.

    Please enter your email address

      Please enter your Comment.

          Related Cheat Sheets

          Selenium WebDriver Cheat Sheet Cheat Sheet
          Cypressio Cheat Sheet
          ISTQB Test Automation Engineering Cheat Sheet