Ruby Active Record Cheat Sheet
Tags: ruby, beginners, programming, activerecord
Published: 2022-09-14 04:08:07

Hello and welcome back to: Cheat Sheets with Karter. 

In today's cheat sheet we will be briefly looking at the beginning steps of ruby's active record functionality.

Copy and paste this into a code editor and see all the pretty colors!

```
--------------------SET UP--------------------

# 1. Run in console to install gems in Gemfile bundle install

# 2. do migrations (see RAKE CONSOLE COMMANDS & MIGRATION FILES)
    # Verify schema file is correct before continuing

# 3. set up Class files if not set up (see CLASSES and everything below it)
    # Set up the has_many & belongs_to relationships first

# 4. set up seeds.rb file if not set up for running tests (see SEED FILE)
    # Run in console to seed data
    bundle exec rake db:seed

# 5. Run console (should have pry in Rakefile task) (see RUNNING TESTS)
    bundle exec rake console
    # can put binding.pry in code anywhere but reset console first
    # to get out of pry => control + D (on mac)

    #reset console/seeds if needed 
    rake db:reset

    # clear console of previous tests (!does not reset console!)
    clear

    # Returns all the methods you can use
    User.methods 
    # OR
    Ruby.methods

-----------RAKE CONSOLE COMMANDS-------------

#          where v      v what do      name of file v
bundle exec rake db:create_migration NAME=create_artists

# write in generated file then can migrate using command below
bundle exec rake db:migrate

# check status of migration
bundle exec rake db:migrate:status

# if mistake, take back mistakes
bundle exec rake db:rollback

---------------MIGRATION FILES---------------

# after doing => bundle exec rake db:create_migration NAME=______

class CreateArtists < ActiveRecord::Migration[6.1]   
  def change

    # create a table called artists with columns (t)
    create_table :artists do |t|

      # v data type 
      t.string :name
      #           ^name of data (column name)

      # v lots of different data types
      t.string :birthdate
      t.integer :age
      t.float :price
      t.datetime :release_date
      t.text :description
      t.boolean :cool 

      t.timestamps
      # ^ creates a created_at column and a updated_at column

      # id column auto generated for every table
      # DO NOT put symbols as part of a data name, 0/10 do not recommend
    end
  end
end

# in def change can also do these if not making table:

#            v table   v new column    v data type
add_column :artists, :favorite_food, :string

#                v table   v column    v new data type
change_column :artists, :birthdate, :datetime

---------------RUNNING TESTS------------------

# if testing an instance's association 
# EX: show all pets that belong to shelter
Shelter.first.pets
# => Class that owns thing . first instance . Class that belongs to it (lowercase and plural)

# if testing the Class method
# EX: return the oldest pet
Pet.oldest
# => Class . method in class

-----------------SEED FILE--------------------
# make a file called seeds.rb in db folder

# if you want to use id from one class in another, save to variable
t1 = Class1.create(key:"value")

# ids are auto generated, so no need to make them
Class2.create(attached_id: t1.id, key1:"value1", key2:2, key3:false)

# highly recommend doing:
puts "Done!"

# so that you know it didn't freeze on you.

------------------CLASSES------------------

# Must inherit Active Record in order to get all the cool shit
class Dog < ActiveRecord::Base 
    belongs_to :pet 
    # Dog is part of Pet

    has_many :appointments
    # Dog has many appointments

    has_many :doctors, through: :appointments
    # Dog has many doctors through appointments

    @@dog_count = 0
    # class variable

    def initialize
        # upon initialization
        super
        # do *initialize* from inherited files first
        # can take an arg EX: super(name)

        @@dog_count += 1
        # add 1 to class variable
    end

    def get_adopted(owner_name)
        self.owner = owner_name
        # self refers to the instance of Dog that is being called
    end
end

# objects in Dog are accessed by dot notation
fido = Dog.new("Fido")
# fido = new instance of Dog, passing in "Fido" as name

fido.get_adopted("Sophie")
# sets "Sophie" as owner_name

------------------METHODS------------------

#                               v default value for name
def greet_with_default (name="programmer")
    puts "Hello, #{name}!"
end
# def -> identifies it as a method
    # parentheses are optional if not passing data
    # last line of a method is the return value unless you put return
# end -> end of method (always needed)

------------------------------------------

# keyword args make it less likely to break
def happy_birthday(person:, current_age:)
  puts "Happy Birthday, #{person}"
  current_age += 1
  puts "You are now #{current_age} years old"
end

# call the method with the keywords and values
happy_birthday(current_age: 31, person: "Carmelo Anthony")

------------------------------------------

def self.method 
    self.order
end
# ^self refers to class in both because it's in method name

def method
    self
end
# ^self refers to an instance because it's not in method name

=================ACTIVE RECORD METHODS======================
# more info:
# https://guides.rubyonrails.org/active_record_querying.html
# https://rubydoc.info/stdlib/core/Enumerable:group_by
# https://apidock.com/ruby/Enumerable/group_by

# vv inherit ActiveRecord to get the following vv #

--------attr_accessors are built into Active Record--------

# Class => substitute name of class you want to use
# Class_Instance => substitute instance of a class 

# Can combine things listed below!!

Class.new(___:___)
# creates new instance of class using variables listed in (__)
    # ex: Class.new(name: 'Jon')
# not saved in db until run .save
# can save to var to change instance variables separately

Class_Instance.save
# save changes of an instance to the database

Class.create(___:___)
# create a new entry of Class in database
# .new + .save put together
    # ____ => variables, ex: Class.create(name: 'Jon')

Class.update(____:____)
# updates all instance vars to new data
# also works on instance basis: self.update(__:__) or Class.first.update(__:__)

Class_Instance.update(_____:_____)
# updates instance to new data

Class.all
# returns all the records from the table as instances of Class

Class.column_names
# retrieves a list of all the columns in the table

Class.find(_)
# retrieve a Class object from database by id (_)

Class.find_by(____:____)
# find by any attribute
    # ____ => variables, ex: Class.find_by(name: 'Jon')
    # returns nil if not found

Class.pluck(____)
# returns array of all _____ of the instances of Class
    # EX: Class.pluck(:name) => returns a list of all the instance names in Class

Class.where(___:___)
# find but returns list of all that match query (___:___)

Class.find_or_create_by(___:___)
# Creates instance of class if it does not exist
    # ____ => variables, ex: Class.find_or_create_by(name: 'Jon')

Class.order(___)
# orders the instances for Class by ____
    # EX: Class.order(:name) => orders instances by name

Class.first
# gets first instance created, can do second, third, etc

Class.last
# gets last instance created

Class_Instance.destroy 
# deletes instance

Class.destroy
# deletes last instance created (returns deleted instances)

Class.delete_all
#deletes all instances (returns number of instances deleted)

Class.destroy_all
# deletes all instances (returns deleted instances)

Class.sum(___)
# adds up all of the keys that match

Class.all.length
# returns num of instances in Class

Class_Instance.group_by {|p| p._____}
# EX: (1..6).group_by { |i| i%3 }   
#=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}

```
Please let me know if I'm missing anything :)