Skip to content

Instantly share code, notes, and snippets.

@VictoriaVasys
Created March 31, 2017 22:53
Show Gist options
  • Save VictoriaVasys/2a096a19c3e63882d01271a627bd9ab9 to your computer and use it in GitHub Desktop.
Save VictoriaVasys/2a096a19c3e63882d01271a627bd9ab9 to your computer and use it in GitHub Desktop.
Notes on active record methods and relationships needed for mid-mod

Need-to-know methods

#find() #find_by() #where() #create() == #new() & #save() #update() == #update_attributes() #destroy()

Need-to-know relationships

has_many :things belongs_to :other_thing has_many :widgets, through: :things

thing = Thing.first thing.widgets.create() thing.widgets << [Widget.create(), Widget.create()] thing.other_thing.create()

e.g.s

Curd.create(cheese_type: "swiss", squeak: "CheeeeEEE", crunchiness: "very_crunchy", batter_thickness: "just_right", tasty?: true, order_count: 20, price: 3) Curd.find(1, 2) Curd.where(cheese_type: "gruyère") Curd.find_by squeak: "eeeEEEyu" == Curd.where(squeak: "eeeEEEyu").take

Curd.find_or_create_by(price: 3) do |c|
  c.crunchiness = "very crunchy"
end

(add a bang to raise an exception if the new record is invalid) #find_or_initialize_by

Curd.limit(5) == Curd.take(5) Curd.limit(5).offset(10) Curd.first(3) or Curd.last(4)

#to_sql #find_by_sql

Curd.all Curd.count

#distinct (like #uniq)

Curd.where(crunchiness: "very_crunchy").pluck(:id)
=> [3, 5, 9]
Curd.pluck(:id, :restaurant)
=> [[1, 'whirley go round'], [2, 'woocurds']]

query single or multiple columns; returns array of values

chaining

Curd.where(price: 5).limit(3).pluck(:id)

extract & ?

postgreSQL

Curd.where('extract(year from created_at) = ? and extract(month from created_at) = ?', 2017, "March").count
Curd.where('extract(hour from created_at) between 1 and 6')

SQLite requires strftime (doesn't know extract)

calculations

Curd.average(:price) #minimum #maximum #sum Curd.sum("3 * order_count")

find_each & find_in_batches

Curd.all.each {|curd| curd.name} = very inefficient; use find_each (batches of 1000) or find_in_batches instead

Curd.where(cheese_color: "orange").find_each do |curd|
  curd.destroy
end

^^ can use :batch_size, :start & :finish too (:order & :limit can only be used internally)

string conditions

Curd.where("age >= 2 AND crunchiness == "very crunchy")

hash conditions

only equality, range & subset checking

Curd.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight) Curd.where(orders_count: [5, 7, 8]) Curd.where.not(crunchiness: "soggy")

ordering

Curd.order(:crunchiness) Curd.order(orders_count: :desc) Curd.order("crunchiness, orders_count DESC")

group

gives a single object for each attribute value Order.select("date(created_at) as ordered_date).group("date(created_at)"

creates a hash with the value of the attribute being the key and the number of those values being the value

Order.group(:status).count
# => { 'awaiting_approval' => 7, 'paid' => 12 }

having

Curd.group(:price).having("order_count > ?", 100)

scopes

class Curd < ActiveRecord::Base
  scope :tasty, -> { where(tasty: true) }
end

same as:

class Curd < ActiveRecord::Base
  def self.tasty
    where(tasty: true)
  end
end

chainable:

class Curd < ActiveRecord::Base
  scope :tasty, -> { where(tasty: true) }
  scope :tasty_and_cheap -> {tasty.where("price < 5")}
end

can call on class or association consisting of Curd objects Curd.tasty = [tasty curds] Order.first.curds.tasty

raising errors

use !; will raise ActiveRecord::RecordNotFound error if they do not return any records

exists?

Curd.exists? Curd.exists?(5) Curd.exists?(id: [1,2,5]) # true if any one of them exists)

Curd.any? Curd.many?

Curd.where(crunchiness: "very crunchy").any? Curd.where(crunchiness: "very crunchy").many?

Curd.first.sauces.any? Curd.first.sauces.many?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment