Created
February 14, 2017 21:13
-
-
Save rob0t7/43bef56ece6d1e04c5865177a7ab8cb8 to your computer and use it in GitHub Desktop.
AR Breakout
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'pry' | |
require 'active_record' | |
ActiveRecord::Base.logger = Logger.new(STDOUT) | |
# Objects that we will be using | |
class Customer < ActiveRecord::Base | |
has_many :invoices | |
validates :first_name, presence: true | |
validates :last_name, presence: true | |
validates :email, presence: true, | |
uniqueness: true, | |
format: /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i | |
before_validation { self.email = email.downcase } | |
def self.find_by_email(email) | |
find_by(email: email.downcase) | |
end | |
def name | |
"#{first_name} #{last_name}" | |
end | |
end | |
class Product < ActiveRecord::Base | |
#has_and_belongs_to_many :invoices #for pure many-to-many relationship | |
has_many :invoice_items | |
has_many :invoices, through: :invoice_items # many-to-many relations using an itermediate table | |
validates :name, presence: true | |
validates :description, presence: true | |
validates :price_cents, numericality: { only_integer: true, greater_than_or_equal_to: 0 } | |
validates :inventory, numericality: { only_integer: true, greater_than_or_equal_to: 0 } | |
end | |
class Invoice < ActiveRecord::Base | |
belongs_to :customer | |
belongs_to :shipping_address, class_name: 'Address' | |
belongs_to :billing_address, class_name: 'Address' | |
has_many :invoice_items, autosave: true | |
has_many :products, through: :invoice_items # many-to-many relations using an itermediate table | |
def total_price | |
invoice_items.reduce(0) { |total, x| total + x.price_cents } | |
end | |
end | |
class InvoiceItem < ActiveRecord::Base | |
belongs_to :invoice | |
belongs_to :product | |
after_create :update_inventory | |
private | |
def update_inventory | |
product_inventory = product.inventory | |
product.update(inventory: product_inventory - quantity) | |
end | |
end | |
class Address < ActiveRecord::Base | |
belongs_to :customer | |
end | |
puts "Establishing connection to Database" | |
ActiveRecord::Base.establish_connection( | |
adapter: 'postgresql', | |
database: 'ar_breakout', | |
username: 'rob', | |
encoding: 'unicode' | |
) | |
puts "Creating DB Schema" | |
ActiveRecord::Schema.define do | |
drop_table :customers if ActiveRecord::Base.connection.table_exists?(:customers) | |
drop_table :invoices if ActiveRecord::Base.connection.table_exists?(:invoices) | |
drop_table :invoice_items if ActiveRecord::Base.connection.table_exists?(:invoice_items) | |
drop_table :products if ActiveRecord::Base.connection.table_exists?(:products) | |
drop_table :invoices_products if ActiveRecord::Base.connection.table_exists?(:invoices_products) | |
create_table :customers do |t| | |
t.string :first_name, null: false | |
t.string :last_name, null: false | |
t.string :email, null: false, index: true, unique: true | |
end | |
create_table :products do |t| | |
t.string :name, null: false | |
t.integer :inventory, null: false, default: 0 | |
t.text :description, null: false, default: '' | |
t.integer :price_cents, null: false, default: 0 | |
end | |
create_table :addresses do |t| | |
t.references :customer | |
t.string :address_1 | |
t.string :city | |
end | |
create_table :invoices do |t| | |
t.references :customer, index: true, foreign: true | |
t.datetime :invoice_date, null: false | |
t.references :shipping_address | |
t.references :billing_address | |
end | |
# needed for a pure many-to-many relationship | |
create_table :invoices_products do |t| | |
t.references :product | |
t.references :invoice | |
end | |
create_table :invoice_items do |t| | |
t.references :product | |
t.references :invoice | |
t.integer :price_cents | |
t.integer :quantity | |
end | |
end | |
puts "SEED Database" | |
Customer.create!(first_name: 'Jane', last_name: 'Doe', email: '[email protected]') | |
Customer.create!(first_name: 'John', last_name: 'Smith', email: '[email protected]') | |
Product.create!(name: 'Beer', description: 'Best drink in the world', price_cents: 290, inventory: 100) | |
Product.create!(name: 'Whiskey', description: 'The Scottish like it', price_cents: 100000, inventory: 50) | |
customer.invoices.create!(invoice_date: DateTime.now) | |
customer.invoices.create!(invoice_date: 1.month.ago) | |
puts "Running class code" | |
customer = Customer.find_by_email('[email protected]') | |
# Creating an Invoice with 1 item related to a product | |
product = Product.first | |
invoice = customer.invoices.build(invoice_date: DateTime.now) | |
item = invoice.invoice_items.build(product: product, price_cents: product.price_cents, quantity: 2) | |
invoice.save | |
# after the invoice is save the inventory of the product should decrease by two | |
# <model>.reload reloads the model (ie syncs) from the DB (used a lot in testing) | |
product.reload.inventory == product.inventory - item.quantity |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment