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