#find()
#find_by()
#where()
#create() == #new() & #save()
#update() == #update_attributes()
#destroy()
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()
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
Curd.where(price: 5).limit(3).pluck(:id)
postgreSQL
Curd.where('extract(year from created_at) = ? and extract(month from created_at) = ?', 2017, "March").countCurd.where('extract(hour from created_at) between 1 and 6')SQLite requires strftime (doesn't know extract)
Curd.average(:price)
#minimum
#maximum
#sum
Curd.sum("3 * order_count")
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)
Curd.where("age >= 2 AND crunchiness == "very crunchy")
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")
Curd.order(:crunchiness)
Curd.order(orders_count: :desc)
Curd.order("crunchiness, orders_count DESC")
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 }Curd.group(:price).having("order_count > ?", 100)
class Curd < ActiveRecord::Base
scope :tasty, -> { where(tasty: true) }
endsame as:
class Curd < ActiveRecord::Base
def self.tasty
where(tasty: true)
end
endchainable:
class Curd < ActiveRecord::Base
scope :tasty, -> { where(tasty: true) }
scope :tasty_and_cheap -> {tasty.where("price < 5")}
endcan call on class or association consisting of Curd objects
Curd.tasty = [tasty curds]
Order.first.curds.tasty
use !; will raise ActiveRecord::RecordNotFound error if they do not return any records
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?