Skip to content

Instantly share code, notes, and snippets.

@rs-ehyde
Last active March 8, 2021 21:29
Show Gist options
  • Save rs-ehyde/0cdc7d4b33ae21ba0318f5f84c1681fd to your computer and use it in GitHub Desktop.
Save rs-ehyde/0cdc7d4b33ae21ba0318f5f84c1681fd to your computer and use it in GitHub Desktop.
Ruby/Rails Cheatsheet
# According to Ruby’s official web page, Ruby is a:
"dynamic, open source programming language with a focus on simplicity and productivity."
"It has an elegant syntax that is natural to read and easy to write."
# Basic syntactical code:
variable_name = 'sillyboys' # no semicolons, untyped
def method_name do
puts 'lol' # no parentheses needed for method calls if no chaining
# puts is the standard "console.log"
end
# //////////////////////////////////////////////////////
# CLASSES / PARAMS
# //////////////////////////////////////////////////////
# let's say params is some { hash object } that holds a key and a value, i.e.
# { key: value }, or for the purposes of this example:
# person = { name: 'Nathan' }
# person[:name] == 'Nathan' is true,
# with the :key syntax being "symbol notation".
# you can also make hashes with string syntax, i.e.
# { 'name' => 'Nathan' }
# this is helpful for some particular cases when we need to parse the
# key value, but for the most part, idiomatically, we use symbol notation
class Person do
# this allows us to reference 'name' as an instance variable outside and inside the class
attr_accessor :name
# called on .new()
def initialize(params) do
@name = params[:name] # the @ symbol means it is an instance variable. It is made accessible without the @ symbol by attr_accessor.
end
def int_of_three do
3 # automatically returns last line in method
end
def string_with_name do
"person's name is #{name}" # string interpolation, must use double quotes
# standard is to use single quotes unless using interpolation
end
def is_nathan? do # conventional to add question mark to boolean methods
name == 'Nathan'
end
def change_name!(new_name) do # a '!' suggests object is changing inherently
name = new_name
end
end
example = Person.new { name: 'Nathan' }
# both types of param parsing may work depending on the object
example[:name] == 'Nathan' # true
example.name == 'Nathan' # true
# //////////////////////////////////////////////////////
# LOOPS / MAPS
# //////////////////////////////////////////////////////
# so let's talk about a couple looping methods that may be unusual
names = ['Emma', 'Nathan', 'Tom'] # just a list of Strings, not of class Person
names.each do |name| # for each item in 'names', referenced by 'name'
puts name # print name to the console
end
# standard for/each loop... but let's say we wanted to make a modification to names,
# like add the last name "smith" to all of them. in many languages, we'd copy out
# the array itself, make modifications, and save the new array to a new variable:
names_new = []
names.each do |name|
names_new << "#{name} Smith"
end
names_new
# note that the .each doesn't natively collect the results.
# If we weren't saving those transformations manually, these modifications would get dropped on the floor.
# But, ruby is all about SIMPLICITY, PRODUCTIVITY, and READABILITY. A cleaner way to write this is:
names = names.map do |name|
"#{name} Smith" # implicit return
end
# the .map functionality, assigns a new iterable to the variable 'names',
# the contents being A COLLECTION OF THE RETURNED VALUES FROM EACH LOOP.
# What is the difference between map & each?
# Each is like a more primitive version of map…
# It gives you every element so you can work with it, but it doesn’t collect the results.
# Each always returns the original, unchanged object.
# While map does the same thing, but…
# It returns a new array with the transformed elements.
# but, what if 'name' is null (or in ruby, 'nil')?
names = names.map do |name|
if !name.blank?
"#{name} Smith"
end
end
# or use ruby's 'unless'...
names = names.map do |name|
"#{name} Smith" unless name == nil
end
# we can also append if statements to the end of a line in this same way...
names = names.map do |name|
"#{name} Smith" if name != nil
end
# which is the equivalent of its expanded version:
names = names.map do |name|
if name != nil
"#{name} Smith"
end
end
# if you have an array of parseable objects, i.e. "PERSONS", we can use the SAFE NAVIGATION OPERATOR
# instead of a standard nil value check.
persons = [Person.new('Emma'), Person.new('Nathan'), Person.new('Tom')]
# safely navigates using dot notation
persons.map do |person|
person&.name
end
# safely navigates using hash notation
persons.map do |person|
person.dig(:name)
end
# we can assign a variable IF it has not been assigned yet with "memoization"
variable ||= 'Nathan'
variable ||= 'Emma'
variable == 'Nathan' # true
# if we want to modify an object we're getting back from some operation on the fly,
# we can .tap into that object before we return it.
person = Person.new.tap do |person|
person.name = "Emma"
end
# same as
person = Person.new { name: 'Emma' }
# //////////////////////////////////////////////////////
# CONVENTIONS
# //////////////////////////////////////////////////////
# methods with !
# Assuming 'name' is a required param of User...
user = User.create(name: 'Barnacle')
#=> User<# name: 'Barnacle', id: nil>
user.save
#=> User<# name: 'Barnacle', id: 1>
user = User.create(name: nil)
#=> User<# name: nil, id: nil>
user.valid?
#=> false
user.save
#=> false
#----RESET----#
# the Bang (!) denotes that a method will raise an error, e.g.
# ActiveRecord::RecordInvalid if validation fails.
user = User.create!(name: 'Barnacle')
#=> User<# name: 'Barnacle', id: 1>
user = User.create!(name: nil)
#=> Error ActiveRecord::RecordInvalid
# methods with ? are boolean methods that return true or false.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment