| Class | Ohm::Model |
| In: |
lib/ohm.rb
lib/ohm/json.rb |
| Parent: | Object |
The base class for all your models. In order to better understand it, here is a semi-realtime explanation of the details involved when creating a User instance.
Example:
class User < Ohm::Model
attribute :name
index :name
attribute :email
unique :email
counter :points
set :posts, :Post
end
u = User.create(:name => "John", :email => "foo@bar.com")
u.increment :points
u.posts.add(Post.create)
When you execute `User.create(...)`, you run the following Redis commands:
# Generate an ID INCR User:id # Add the newly generated ID, (let's assume the ID is 1). SADD User:all 1 # Store the unique index HSET User:uniques:email foo@bar.com 1 # Store the name index SADD User:indices:name:John 1 # Store the HASH HMSET User:1 name John email foo@bar.com
Next we increment points:
HINCR User:1:counters points 1
And then we add a Post to the `posts` set. (For brevity, let‘s assume the Post created has an ID of 1).
SADD User:1:posts 1
| id | [W] |
The bread and butter macro of all models. Basically declares persisted attributes. All attributes are stored on the Redis hash.
class User < Ohm::Model
attribute :name
end
user = User.new(name: "John")
user.name
# => "John"
user.name = "Jane"
user.name
# => "Jane"
A lambda can be passed as a second parameter to add typecasting support to the attribute.
class User < Ohm::Model
attribute :age, ->(x) { x.to_i }
end
user = User.new(age: 100)
user.age
# => 100
user.age.kind_of?(Integer)
# => true
Check rubydoc.info/github/cyx/ohm-contrib#Ohm__DataTypes to see more examples about the typecasting feature.
A macro for defining a method which basically does a find.
Example:
class Post < Ohm::Model
reference :user, :User
end
class User < Ohm::Model
collection :posts, :Post
end
# is the same as
class User < Ohm::Model
def posts
Post.find(:user_id => self.id)
end
end
Declare a counter. All the counters are internally stored in a different Redis hash, independent from the one that stores the model attributes. Counters are updated with the `increment` and `decrement` methods, which interact directly with Redis. Their value can‘t be assigned as with regular attributes.
Example:
class User < Ohm::Model
counter :points
end
u = User.create
u.increment :points
u.points
# => 1
Note: You can‘t use counters until you save the model. If you try to do it, you‘ll receive an Ohm::MissingID error.
Find values in indexed fields.
Example:
class User < Ohm::Model
attribute :email
attribute :name
index :name
attribute :status
index :status
index :provider
index :tag
def provider
email[/@(.*?).com/, 1]
end
def tag
["ruby", "python"]
end
end
u = User.create(name: "John", status: "pending", email: "foo@me.com")
User.find(provider: "me", name: "John", status: "pending").include?(u)
# => true
User.find(:tag => "ruby").include?(u)
# => true
User.find(:tag => "python").include?(u)
# => true
User.find(:tag => ["ruby", "python"]).include?(u)
# => true
Declare an Ohm::List with the given name.
Example:
class Comment < Ohm::Model
end
class Post < Ohm::Model
list :comments, :Comment
end
p = Post.create
p.comments.push(Comment.create)
p.comments.unshift(Comment.create)
p.comments.size == 2
# => true
Note: You can‘t use the list until you save the model. If you try to do it, you‘ll receive an Ohm::MissingID error.
A macro for defining an attribute, an index, and an accessor for a given model.
Example:
class Post < Ohm::Model
reference :user, :User
end
# It's the same as:
class Post < Ohm::Model
attribute :user_id
index :user_id
def user
@_memo[:user] ||= User[user_id]
end
def user=(user)
self.user_id = user.id
@_memo[:user] = user
end
def user_id=(user_id)
@_memo.delete(:user_id)
self.user_id = user_id
end
end
Retrieve a set of models given an array of IDs.
Example:
ids = [1, 2, 3] ids.map(&User)
Note: The use of this should be a last resort for your actual application runtime, or for simply debugging in your console. If you care about performance, you should pipeline your reads. For more information checkout the implementation of Ohm::List#fetch.
Returns a hash of the attributes with their names as keys and the values of the attributes as values. It doesn‘t include the ID of the model.
Example:
class User < Ohm::Model
attribute :name
end
u = User.create(:name => "John")
u.attributes
# => { :name => "John" }
Decrements a counter atomically. Internally uses `HINCRBY`.
class Post
counter :score
end
post = Post.create
post.decrement(:score)
post.score # => -1
post.decrement(:hits, 2)
post.score # => -3
Read an attribute remotely from Redis. Useful if you want to get the most recent value of the attribute and not rely on locally cached value.
Example:
User.create(:name => "A")
Session 1 | Session 2
--------------|------------------------
u = User[1] | u = User[1]
u.name = "B" |
u.save |
| u.name == "A"
| u.get(:name) == "B"
Return a value that allows the use of models as hash keys.
Example:
h = {}
u = User.new
h[:u] = u
h[:u] == u
# => true
Increments a counter atomically. Internally uses `HINCRBY`.
class Ad
counter :hits
end
ad = Ad.create
ad.increment(:hits)
ad.hits # => 1
ad.increment(:hits, 2)
ad.hits # => 3
Returns the namespace for the keys generated using this model. Check `Ohm::Model.key` documentation for more details.
Returns true if the model is not persisted. Otherwise, returns false.
Example:
class User < Ohm::Model
attribute :name
end
u = User.new(:name => "John")
u.new?
# => true
u.save
u.new?
# => false
Export the ID of the model. The approach of Ohm is to whitelist public attributes, as opposed to exporting each (possibly sensitive) attribute.
Example:
class User < Ohm::Model
attribute :name
end
u = User.create(:name => "John")
u.to_hash
# => { :id => "1" }
In order to add additional attributes, you can override `to_hash`:
class User < Ohm::Model
attribute :name
def to_hash
super.merge(:name => name)
end
end
u = User.create(:name => "John")
u.to_hash
# => { :id => "1", :name => "John" }
Update the model attributes and call save.
Example:
User[1].update(:name => "John") # It's the same as: u = User[1] u.update_attributes(:name => "John") u.save