Home

Overriding accessors

class Song < ActiveRecord::Base
  # Uses an integer of seconds to hold the length of the song

  def length=(minutes)
    write_attribute(:length, minutes.to_i * 60)
  end

  def length
    read_attribute(:length) / 60
  end
end

See: http://api.rubyonrails.org/classes/ActiveRecord/Base.html

Callbacks

  • after_create
  • after_initialize
  • after_validation
  • after_save
  • after_commit

Serialize

class User < ActiveRecord::Base
  serialize :preferences
end
user = User.create(
  preferences: {
    'background' => 'black',
    'display' => 'large'
  }
)

You can also specify a class option as the second parameter that’ll raise an exception if a serialized object is retrieved as a descendant of a class not in the hierarchy.

# Only Hash allowed!
class User < ActiveRecord::Base
  serialize :preferences, Hash
end
# Reading it raises SerializationTypeMismatch
user = User.create(preferences: %w(one two three))
User.find(user.id).preferences

Other tricks

Where interpolation

where('name = ?', 'John')
where(['name = :name', { name: 'John' }])

Joining

# Basic joins
Student.joins(:schools).where(schools: { type: 'public' })
Student.joins(:schools).where('schools.type' => 'public' )
# Multiple associations
Article.joins(:category, :comments)
# Nested associations
Article.joins(comments: :guest)
# SQL
Author.joins(
  'INNER JOIN posts ' +
  'ON posts.author_id = authors.id ' +
  'AND posts.published = "t"'
)

Mass updates

# Updates person id 15
Person.update 15, name: "John", age: 24
Person.update [1,2], [{name: "John"}, {name: "foo"}]

Callbacks

Errors

record.errors.valid?      # → false
record.errors             # → { :name => ["can't be blank"] }
record.errors.messages    # → { :name => ["can't be blank"] }
record.errors[:name].any?

Other API

Custom validations

class Person < ActiveRecord::Base
  validate :foo_cant_be_nil

  def foo_cant_be_nil
    errors.add(:foo, 'cant be nil')  if foo.nil?
  end
end

Validation

class Person < ActiveRecord::Base
  # Presence
  validates :name,     presence: true
  # Acceptance
  validates :terms,    acceptance: true
  # Confirm
  validates :email,    confirmation: true
  # Unique
  validates :slug,     uniqueness: true
  validates :slug,     uniqueness: { case_sensitive: false }
  validates :holiday,  uniqueness: { scope: :year, message: 'yearly only' }
  # Format
  validates :code,     format: /regex/
  validates :code,     format: { with: /regex/ }
  # Length
  validates :name,     length: { minimum: 2 }
  validates :bio,      length: { maximum: 500 }
  validates :password, length: { in: => 6..20 }
  validates :number,   length: { is: => 6 }
  # Include/exclude
  validates :gender,   inclusion: %w(male female)
  validates :gender,   inclusion: { in: %w(male female) }
  validates :lol,      exclusion: %w(xyz)
  # Numeric
  validates :points,   numericality: true
  validates :played,   numericality: { only_integer: true }
  # ... greater_than, greater_than_or_equal_to,
  # ... less_than, less_than_or_equal_to
  # ... odd, even, equal_to
  # Validate the associated records to ensure they're valid as well
  has_many :books
  validates_associated :books
  # Length (full options)
  validates :content, length: {
    minimum:   300,
    maximum:   400,
    tokenizer: lambda { |str| str.scan(/\w+/) },
    too_short: "must have at least %{count} words",
    too_long:  "must have at most %{count} words" }
  # Multiple
  validates :login, :email, presence: true
  # Conditional
  validates :description, presence: true, if: :published?
  validates :description, presence: true, if: lambda { |obj| .. }
  validates :title, presence: true, on: :save   # :save | :create | :update
end

Polymorphic associations

class Post
  has_many :attachments, as: :parent
end
class Image
  belongs_to :parent, polymorphic: true
end

And in migrations:

create_table :images do |t|
  t.references :post, polymorphic: true
end

Validation

Many-to-many (HABTM)

has_and_belongs_to_many :projects
has_and_belongs_to_many :projects, :include => [ :milestones, :manager ]
has_and_belongs_to_many :nations, :class_name => "Country"
has_and_belongs_to_many :categories, :join_table => "prods_cats"
has_and_belongs_to_many :categories, :readonly => true
has_and_belongs_to_many :active_projects, :join_table => 'developers_projects', :delete_sql =>
"DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}"

Many-to-many

If you have a join model: {: .-setup}

class Programmer < ActiveRecord::Base
  has_many :assignments
  has_many :projects, :through => :assignments
end

{: data-line="2,3"}

class Project < ActiveRecord::Base
  has_many :assignments
  has_many :programmers, :through => :assignments
end

{: data-line="2,3"}

class Assignment
  belongs_to :project
  belongs_to :programmer
end

{: data-line="2,3"}

belongs to

belongs_to :author,
  :dependent      => :destroy    # or :delete

  :class_name     => "Person"
  :select         => "*"
  :counter_cache  => true
  :counter_cache  => :custom_counter
  :include        => "Book"
  :readonly       => true

  :conditions     => 'published = true'

  :touch          => true
  :touch          => :authors_last_updated_at

  :primary_key    => "name"
  :foreign_key    => "author_name"

Has many

belongs_to :parent, :foreign_key => 'parent_id' class_name: 'Folder'
has_many :folders, :foreign_key => 'parent_id', class_name: 'Folder'

has_many :comments,                -> { order('posted_on DESC') }
has_many :comments,    :include    => :author
has_many :people,      :class_name => "Person"
has_many :people,      :conditions => "deleted = 0"
has_many :tracks,                  -> { order(:position) }
has_many :comments,    :dependent  => :nullify
has_many :comments,    :dependent  => :destroy
has_many :tags,        :as         => :taggable
has_many :reports,     :readonly   => true
has_many :subscribers, :through    => :subscriptions, class_name: "User", :source => :user
has_many :subscribers, :finder_sql =>
    'SELECT DISTINCT people.* ' +
    'FROM people p, post_subscriptions ps ' +
    'WHERE ps.post_id = #{id} AND ps.person_id = p.id ' +
    'ORDER BY p.first_name'

Associations

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

Dynamic attribute-based finders

Given a field called name: {: .-setup}

# Returns one record
Person.find_by_name(name)
Person.find_last_by_name(name)
Person.find_or_create_by_name(name)
Person.find_or_initialize_by_name(name)
# Returns a list of records
Person.find_all_by_name(name)
# Add a bang to make it raise an exception
Person.find_by_name!(name)
# You may use `scoped` instead of `find`
Person.scoped_by_user_name

Associations

Calculations

Person.count
Person.count(:age)    # counts non-nil's
Person.average(:age)
Person.maximum(:age)
Person.minimum(:age)
Person.sum('2 * age')
Person.calculate(:count, :all)

Advanced:

Person.distinct.count
Person.group(:city).count

See: Calculations

Validations

item.valid?
item.invalid?

See: Validations

Dirty

item.changed?
item.changed             # ['name']
item.changed_attributes  # { 'name' => 'Bob' } - original values
item.changes             # { 'name' => ['Bob', 'Robert'] }
item.previous_changes    # available after #save
item.restore_attributes
item.name = 'Robert'
item.name_was         # 'Bob'
item.name_change      # [ 'Bob', 'Robert' ]
item.name_changed?    # true
item.name_changed?(from: 'Bob', to: 'Robert')

See: Dirty

Attribute Assignment

item.attributes                      # #<Hash>
item.attributes = { name: 'John' }   # Merges attributes in. Doesn't save.
item.assign_attributes name: 'John'  # Same as above

See: AttributeAssignment

Persistence

item.new_record?
item.persisted?
item.destroyed?

item.serialize_hash
item.save
item.save!      # Same as above, but raises an Exception
item.update  name: 'John'  # Saves immediately
item.update! name: 'John'
item.update_column  :name, 'John'  # skips validations and callbacks
item.update_columns  name: 'John'
item.update_columns! name: 'John'
item.touch                 # updates :updated_at
item.touch :published_at
item.destroy
item.delete  # skips callbacks
Model.create     # Same an #new then #save
Model.create!    # Same as above, but raises an Exception

See: Persistence

Finder methods

item = Model.find(id)
item = Model.find_by_email(email)
item = Model.where(email: email).first
Model
  .exists?(5)
  .exists?(name: "David")
  .first
  .last
  .find_nth(4, [offset])

See: FinderMethods

Advanced query methods

items = Model
  .select(:id)
  .select([:id, :name])
  .group(:name)   # GROUP BY name
  .group('name AS grouped_name, age')
  .having('SUM(price) > 30')  # needs to be chained with .group
  .includes(:user)
  .includes(user: [:articles])
  .references(:posts)
  # aka: .where("posts.name = 'foo'").references(:posts)

Query methods

items = Model
  .where(first_name: 'Harvey')
  .where('id = 3')
  .where('id = ?', 3)
  .order(:title)
  .order(title: :desc)
  .order("title DESC")
  .reorder(:title)  # discards other .order's
  .rewhere(...)     # discards other .where's
  .limit(2)
  .offset(1)
  .uniq

See: QueryMethods

Generating

$ rails g model User

Using models

More

Dplyr

dplyr cheat sheet is a quick reference for dplyr that is a grammar of data manipulation, providing a consistent set of verbs that help you solve the most common data manipulation challenges.

Regex

A regular expression is a sequence of characters that specifies a search pattern.

PySpark

PySpark is an interface for Apache Spark in Python. It not only allows you to write Spark applications using Python APIs

Golang

Go is a statically typed, compiled programming language designed at Google by Robert Griesemer, Rob Pike, and Ken Thompson.

Watchman

Watchman exists to watch files and record when they change. It can also trigger actions (such as rebuilding assets) when matching files change.

Rollup.Js

Rollup Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application.

Bluebird.Js

Bluebird is a fully-featured Promise library for JavaScript. The strongest feature of Bluebird is that it allows you to "promisify" other Node modules in order to use them asynchronously. Promisify is a concept applied to callback functions.

Flow

Flow is a static type checker for your JavaScript code. It does a lot of work to make you more productive. Making you code faster, smarter, more confidently, and to a bigger scale.

Node.Js Api

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

C Preprocessor

Quick reference for the C macro preprocessor, which can be used independent of C/C++.

Sass

Sass is a preprocessor scripting language that is interpreted or compiled into Cascading Style Sheets. SassScript is the scripting language itself. Sass consists of two syntaxes.

Activeadmin

Active Admin is a Ruby on Rails plugin for generating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very little effort.

Fetch

The Fetch standard defines requests, responses, and the process that binds them: fetching.

Httpie

$ http POST http://example.com name="John" Host:example.com — JSON, cookies, files, auth, and other httpie examples.

Rspec

RSpec is a computer domain-specific language testing tool written in the programming language Ruby to test Ruby code. It is a behavior-driven development framework which is extensively used in production applications.

Saucelabs

Sauce Labs allows users to run tests in the cloud on more than 700 different browser platforms, operating systems, and device combinations.

Jasmine

Jasmine is a behavior-driven development framework for testing JavaScript code.

Sequelize

Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server.

Ubuntu

Ubuntu is a Linux distribution based on Debian and composed mostly of free and open-source software. Ubuntu is officially released in three editions: Desktop, Server, and Core for Internet of things devices and robots.

Rails Models

Ruby on Rails, or Rails, is a server-side web application framework written in Ruby under the MIT License. Rail is a model–view–controller framework, providing default structures for a database, a web service, and web pages.

Git Log

Git is software for tracking changes in any set of files, usually used for coordinating work among programmers collaboratively developing source code during software development.

Controllers

Ruby on Rails, or Rails, is a server-side web application framework written in Ruby under the MIT License. Rails is a model–view–controller framework, providing default structures for a database, a web service, and web pages.

Ansible Examples

Ansible is an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code.

Bolt Quickstart

A quick guide to getting started writing Bolt tasks

Rspec-Rails

RSpec Rails defines ten different types of specs for testing different parts of a typical Rails application.

Rsync

rsync is a utility for efficiently transferring and synchronizing files between a computer and an external hard drive and across networked computers by comparing the modification times and sizes of files.

Ledger Cli

Ledger is a command-line based double-entry bookkeeping application. Accounting data is stored in a plain text file, using a simple format, which the users prepare themselves using other tools.

Homebrew

Homebrew is a free and open-source software package management system that simplifies the installation of software on Apple's operating system macOS as well as Linux.

Bundler

Bundler provides a consistent environment for Ruby projects by tracking and installing the exact gems and versions that are needed.