Skip to content

Instantly share code, notes, and snippets.

@rob0t7
Created July 6, 2016 16:04
Show Gist options
  • Save rob0t7/1d8032b3f123d4c0b6142dffb54d43f0 to your computer and use it in GitHub Desktop.
Save rob0t7/1d8032b3f123d4c0b6142dffb54d43f0 to your computer and use it in GitHub Desktop.
Intro to ActiveRecord
require 'active_record'
require 'pry'
require 'pg'
# Set up logger
#ActiveRecord::Base.logger = ActiveSupport::Logger.new(File.open('database.log', 'w'))
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
# Set up connection
ActiveRecord::Base.establish_connection(
adapter: 'postgresql',
database: 'active_record_store'
)
# Set up the schema of the database
ActiveRecord::Schema.define do
drop_table(:products) if table_exists?(:products)
create_table :products do |t|
t.string :name, null: false
t.text :description, null: false, default: ''
t.decimal :price, null: false, default: 0
t.timestamps null: false
end
drop_table(:orders) if table_exists?(:orders)
create_table :orders do |t|
t.references :product, null: false, index: true
t.string :first_name, null: false
t.string :last_name, null: false
t.string :email, null: false
t.decimal :price, null: false
t.integer :quantity, null: false, default: 1
t.timestamps null: false
end
end
# Now the models
class Product < ActiveRecord::Base
has_many :orders
validates :name, presence: true
validates :description, presence: true
validates :price, numericality: {greater_than_or_equal_to: 0}
# Creates a new order for a customer and copies the current price
# to the order object
def create_order(first_name, last_name, email, quantity)
orders.create(first_name: first_name, last_name: last_name, email: email, quantity: quantity, price: price)
end
end
class Order < ActiveRecord::Base
belongs_to :product
validates :first_name, presence: true
validates :last_name, presence: true
validates :email, presence: true, format: /\b[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}\z/
validates :price, presnce: true, numericality: { greater_than_or_equal_to: 0 }
validates :quantity, presence: true, numericality: { greater_than: 0 }
# Make sure all emails are lowercase in the DB
before_save { self.email.downcase! }
def name
"#{first_name} #{last_name}"
end
def total_price
price * quantity
end
end
#
# Lets create some objects
#
product1 = Product.new(name: 'Product 1', description: 'This is product 1', price: 50)
product1.save
product2 = Product.create(name: 'Product 2', description: 'This is product 2', price: 100)
# save runs validation rules first. If they fail then save fails (and create since it uses save underneath)
product3 = Product.new(description: 'This is product 3', price: 200)
product3.save # returns false
product3.errors # returns the errors
product3.name = 'Product 3'
product3.save # this works
order1 = product1.create_order('Bob', "Smith", '[email protected]', 2)
order1.total_price # == 100.00
product1.create_order('Jane', 'Doe', '[email protected]', 1)
product1.orders # returns the two orders that are in the DB
order3 = Order.new(first_name: 'John',
last_name: 'Smith',
email: '[email protected]',
product: product2,
quantity: 1,
price: 5
)
order3.save # it lowercases the email address and inserts it as [email protected]
product3.orders.create_order('John', 'Smith', '[email protected]', 4)
#
# Queries
#
# find all the products
Product.all
#find all product with price > 100
Product.where('price > ?', 100)
#find all products with price > 100 and price < 200 order by name desc
Product.where('price > ?', 100).where('price < 200').order(name: :desc)
# Remove product2 (find using primary key)
Product.find(2).destroy
# Find all products that '[email protected]' has bought
# In efficient way (without joins)
product_with_orders = []
Product.all.each do |product|
product_with_orders << product if product.orders.exists?(email: '[email protected]')
end
# return product_with_orders
# now using joins (1 DB call vs N+1)
Product.joins(:orders).where(orders: {email: '[email protected]'})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment