Vlado Cingel
vlado@cingel.hr
Čačinci
?
A person who sells services to employers without a long-term commitment to any of them
1995
I wanted to design my own language to maximize my freedom
I wanted to design a language in which I could love programming
Matz
http://objectgraph.rubyforge.org/dotOG.html
I wanted a scripting language that was more powerful than Perl, and more object-oriented than Python
5.times { print "Ruby" }
Minimal interface between webservers supporting Ruby and Ruby frameworks
"dhh"
2003
Ruby on Rails is an open-source web framework that's optimized for programmer happiness and sustainable productivity. It lets you write beautiful code by favoring convention over configuration
Model, View, Controller
primjer
Zadaća validacije
class Person < ActiveRecord::Base
end
p = Person.new(:name => "Vlado Cingel")
p.persisted? # false
p.save # true
p.persisted? # true
Kada se događa validacija?
valid? / invalid?
class Person < ActiveRecord::Base
validates :name, :presence => true
end
Person.create(:name => "Vlado Cingel").valid? # => true
Person.create(:name => nil).valid? # => false
Person.create(:name => "Vlado Cingel").invalid? # => false
Person.create(:name => nil).invalid? # => true
Errors
class Person < ActiveRecord::Base
validates :name, :presence => true
end
p = Person.new
p.errors # {}
p = Person.create
p.errors # {:name=>["can't be blank"]}
p.errors[:name] # ["can't be blank"]
Helpers
ActiveModel::Validations::HelperMethods
+ Custom validations
Definiranje
class User < ActiveRecord::Base
validates :login, :email, :presence => true
before_create do |user|
user.name = user.login.capitalize if user.name.blank?
end
end
false ili exception otkazuju akciju i aktiviraju rollback
Novi objekt
Postojeći objekt
Brisanje objekta
Ostali
Asociacija je veza između dva Active Record modela
Tipovi asocijacija
belongs_to
has_one
has_many
has_many :through
has_one :through
has_and_belongs_to_many
Polymorphic Associations
Model može pripadati (belongs_to) više nego jednom modelu
Dohvat iz baze
Finder methods
Dohvat pojedinog objekta
Client.find(10)
# => SELECT * FROM clients WHERE (clients.id = 10) LIMIT 1
Dohvat pojedinog objekta
Client.first
# => SELECT * FROM clients LIMIT 1
Dohvat pojedinog objekta
Client.last
# => SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1
Dohvat više objekata od jednom
Client.find(1, 10)
# => SELECT * FROM clients WHERE (clients.id IN (1,10))
Uvjeti - String
Client.where("orders_count = 2")
# => SELECT * FROM clients WHERE (orders_count = 2)
Uvjeti - Array
Client.where("orders_count = ? AND locked = ?", 2, false)
# => SELECT * FROM clients WHERE (orders_count = 2 AND locked = 'f')
Client.where("orders_count = :count AND locked = :locked", {:count => 2, :locked => false})
# => SELECT * FROM clients WHERE (orders_count = 2 AND locked = 'f')
Uvjeti - Hash
Client.where(:orders_count => 2)
# => SELECT * FROM clients WHERE (orders_count = 2)
Client.where(:orders_count => 2, :locked => false)
# => SELECT * FROM clients WHERE (orders_count = 2 AND locked = 'f')
Client.where(:orders_count => 2).where(:locked => false)
# => SELECT * FROM clients WHERE (orders_count = 2 AND locked = 'f')
Uvjeti - Hash
Client.where(:created_at => (Time.now.midnight - 1.day)..Time.now.midnight)
# => SELECT * FROM clients WHERE (clients.created_at BETWEEN '2012-12-11 00:00:00' AND '2012-12-12 00:00:00')
Client.where(:orders_count => [1,3,5])
# => SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
Order
Client.order("created_at")
# => SELECT * FROM clients ORDER BY created_at
Client.order("orders_count ASC, created_at DESC")
# => SELECT * FROM clients ORDER BY orders_count ASC, created_at DESC
Select
Client.select("viewable_by, locked")
# => SELECT viewable_by, locked FROM clients
Limit, Offset
Client.limit(5)
# => SELECT * FROM clients LIMIT 5
Client.limit(5).offset(30)
# => SELECT * FROM clients LIMIT 5 OFFSET 30
Joins
Client.joins('LEFT OUTER JOIN addresses ON addresses.client_id = clients.id')
# => SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id = clients.id
Joins
class Category < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :category
has_many :comments
has_many :tags
end
class Comment < ActiveRecord::Base
belongs_to :post
has_one :guest
end
class Guest < ActiveRecord::Base
belongs_to :comment
end
class Tag < ActiveRecord::Base
belongs_to :post
end
Category.joins(:posts)
# => SELECT categories.* FROM categories
INNER JOIN posts ON posts.category_id = categories.id
Joins - multiple associations
Post.joins(:category, :comments)
# => SELECT posts.* FROM posts
INNER JOIN categories ON posts.category_id = categories.id
INNER JOIN comments ON comments.post_id = posts.id
Joins - nested associations
Post.joins(:comments => :guest)
# => SELECT posts.* FROM posts
INNER JOIN comments ON comments.post_id = posts.id
INNER JOIN guests ON guests.comment_id = comments.id
Joins - Conditions
time_range = (Time.now.midnight - 1.day)..Time.now.midnight
Client.joins(:orders).where('orders.created_at' => time_range)
Client.joins(:orders).where(:orders => {:created_at => time_range})
Scopes
class Post < ActiveRecord::Base
scope :published, where(:published => true)
end
Post.published
# => SELECT * FROM posts WHERE (published = 't')
Scopes
class Post < ActiveRecord::Base
scope :before, lambda { |t| where("created_at < ?", t) }
end
Post.before(Time.zone.now)
Dynamic finders
vlado@cingel.hr