#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").count
Curd.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) }
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
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?