Since Ohm-Contrib was released on May 11, 2010, a lot of changes, cool features, and small removals have happened. This blog post is an attempt to summarize what's available and most useful, although I won't attempt to make this an exhaustive reference in any way.
Timestamping
This is probably the most simple yet useful plugin currently in Ohm::Contrib. Using it is actually pretty simple:
require "ohm"
require "ohm/contrib"
class Post < Ohm::Model
include Ohm::Timestamping
end
Post.new.created_at == nil
# => true
Post.new.updated == nil
# => true
Post.create.created_at.to_s == Time.now.utc.to_s
# => true
Typecasting
Probably one of the most useful yet heavy in the sense that it attempts to solve something a bit more difficult than what the other plugins solve.
Using it is rather simple though:
require "ohm"
require "ohm/contrib"
class Product < Ohm::Model
include Ohm::Typecast
include Ohm::Timestamping
attribute :price, Decimal
attribute :discount, Decimal
typecast :created_at, Time
typecast :updated_at, Time
end
As you can see, you can either declare an attribute
with a type from the
get go, but you may also do it later using the typecast
function.
p = Product.create(:price => "99.50", :discount = "0.50")
p.price * p.discount == 49.75
# => true
p.created_at.respond_to?(:strftime)
# => true
Callbacks
I don't think I even have to explain why this is important: popularized by Martin Fowler in his article entitled CallSuper hooks, a.k.a. callbacks have been an intimate part of our models of late.
require "ohm"
require "ohm/contrib"
class Order < Ohm::Model
include Ohm::Callbacks
attribute :status
before :create, :initialize_status
private
def initialize_status
self.status = "Pending"
end
def after_save
OrderMailer.deliver(self)
end
end
As you can see, you may choose to use macro style callbacks, or instance style ones. The following are all the callbacks available to you:
before_validate
andafter_validate
before_create
andafter_create
before_save
andafter_save
before_update
andafter_update
before_delete
andafter_delete
The Newest Addition: Ohm::Scope
This is pretty useful, and the usecase pretty much came about in a fairly large project (twice actually, with different converging styles arrived at independently).
require "ohm"
require "ohm/contrib"
class Product < Ohm::Model
end
class Order < Ohm::Model
include Ohm::Scope
attribute :status
index :status
reference :product, Product
reference :user, User
scope do
def pending
find(:status => "Pending")
end
def paid
find(:status =>"Paid")
end
def product(product)
find(:product_id => product.id).first
end
end
end
class User < Ohm::Model
collection :orders, Order
end
ipod = Product.create
ipad = Product.create
u = User.create
u.orders.add(Order.create(:status => "Pending", :product => ipod))
u.orders.add(Order.create(:status => "Paid", :product => ipad))
u.orders.pending.include?(ipod)
# => true
u.orders.paid.include?(ipad)
# => true
u.orders.pending.product(ipod) == Order[1]
# => true
u.orders.pending.product(ipad) == nil
# => true
There's more!
Aside from the ones mentioned here, there are also a lot of validation routines, and some marginally helpful, but still handy plugins.
If you want to see more checkout the documentation.