Class: Ohm::Model
- Inherits:
-
Object
- Object
- Ohm::Model
- Includes:
- Model::Validations
- Defined in:
- lib/ohm.rb
Defined Under Namespace
Modules: Validations Classes: Collection, Index, IndexNotFound, List, MissingID, Set, Wrapper
Constant Summary
- @@attributes =
Hash.new { |hash, key| hash[key] = [] }
- @@collections =
Hash.new { |hash, key| hash[key] = [] }
- @@counters =
Hash.new { |hash, key| hash[key] = [] }
- @@indices =
Hash.new { |hash, key| hash[key] = [] }
Instance Attribute Summary (collapse)
Class Method Summary (collapse)
- + (Object) [](id)
- + (Object) all
- + (Object) attr_collection_reader(name, type, model)
-
+ (Object) attribute(name)
Defines a string attribute for the model.
- + (Object) attributes
-
+ (Object) collection(name, model, reference = to_reference)
Define a collection of objects which have a reference to this model.
- + (Object) collections
-
+ (Object) connect(*options)
Makes the model connect to a different Redis instance.
- + (Object) const_missing(name) protected
-
+ (Object) counter(name)
Defines a counter attribute for the model.
- + (Object) counters
- + (Object) create(*args)
- + (Object) define_memoized_method(name, &block)
- + (Object) encode(value)
-
+ (Object) find(hash)
Search across multiple indices and return the intersection of the sets.
-
+ (Object) index(att)
Creates an index (a set) that will be used for finding instances.
- + (Object) indices
-
+ (Object) list(name, model = nil)
Defines a list attribute for the model.
-
+ (Object) reference(name, model)
Define a reference to another object.
-
+ (Object) set(name, model = nil)
Defines a set attribute for the model.
- + (Object) to_proc
- + (Object) to_reference
Instance Method Summary (collapse)
- - (Object) ==(other)
- - (Object) attributes
- - (Object) collections
- - (Object) counters
- - (Object) create
-
- (Object) decr(att, count = 1)
Decrement the counter denoted by :att.
- - (Object) delete
-
- (Object) incr(att, count = 1)
Increment the counter denoted by :att.
- - (Object) indices
-
- (Model) initialize(attrs = {})
constructor
A new instance of Model.
- - (Object) inspect
- - (Object) key(*args) protected
-
- (Object) mutex
Lock the object before executing the block, and release it once the block is done.
- - (Boolean) new?
- - (Object) save
-
- (Object) to_hash
Export the id and errors of the object.
- - (Object) to_json(*args)
- - (Object) update(attrs)
- - (Object) update_attributes(attrs)
- - (Object) write protected
- - (Object) write_remote(att, value) protected
Methods included from Model::Validations
Methods included from Validations
#assert, #assert_format, #assert_numeric, #assert_present, #errors, #valid?, #validate
Constructor Details
- (Model) initialize(attrs = {})
A new instance of Model
563 564 565 566 |
# File 'lib/ohm.rb', line 563 def initialize(attrs = {}) @_attributes = Hash.new { |hash, key| hash[key] = read_remote(key) } update_attributes(attrs) end |
Instance Attribute Details
- (Object) id
323 324 325 |
# File 'lib/ohm.rb', line 323 def id @id or raise MissingID end |
Class Method Details
+ (Object) [](id)
512 513 514 |
# File 'lib/ohm.rb', line 512 def self.[](id) new(:id => id) if exists?(id) end |
+ (Object) all
520 521 522 |
# File 'lib/ohm.rb', line 520 def self.all @all ||= Ohm::Model::Index.new(key(:all), Wrapper.wrap(self)) end |
+ (Object) attr_collection_reader(name, type, model)
496 497 498 499 500 501 502 503 |
# File 'lib/ohm.rb', line 496 def self.attr_collection_reader(name, type, model) if model model = Wrapper.wrap(model) define_memoized_method(name) { Ohm::Model::const_get(type).new(key(name), model, db) } else define_memoized_method(name) { Ohm::const_get(type).new(key(name), db) } end end |
+ (Object) attribute(name)
Defines a string attribute for the model. This attribute will be persisted by Redis as a string. Any value stored here will be retrieved in its string representation.
331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/ohm.rb', line 331 def self.attribute(name) define_method(name) do read_local(name) end define_method(:#{name}=") do |value| write_local(name, value) end attributes << name unless attributes.include?(name) end |
+ (Object) attributes
524 525 526 |
# File 'lib/ohm.rb', line 524 def self.attributes @@attributes[self] end |
+ (Object) collection(name, model, reference = to_reference)
Define a collection of objects which have a reference to this model.
class Comment < Ohm::Model attribute :content reference :post, Post end class Post < Ohm::Model attribute :content collection :comments, Comment reference :author, Person end class Person < Ohm::Model attribute :name # When the name of the reference cannot be inferred, # you need to specify it in the third param. collection :posts, Post, :author end @person = Person.create :name => "Albert" @post = Post.create :content => "Interesting stuff", :author => @person @comment = Comment.create :content => "Indeed!", :post => @post @post.comments.first.content # => "Indeed!" @post..name # => "Albert"
Important: please note that even though a collection is a Set, you should not add or remove objects from this collection directly.
487 488 489 490 |
# File 'lib/ohm.rb', line 487 def self.collection(name, model, reference = to_reference) model = Wrapper.wrap(model) define_method(name) { model.unwrap.find(:#{reference}_id" => send(:id)) } end |
+ (Object) collections
532 533 534 |
# File 'lib/ohm.rb', line 532 def self.collections @@collections[self] end |
+ (Object) connect(*options)
Makes the model connect to a different Redis instance.
728 729 730 |
# File 'lib/ohm.rb', line 728 def self.connect(*) self.db = Ohm.connection(*) end |
+ (Object) const_missing(name) (protected)
764 765 766 |
# File 'lib/ohm.rb', line 764 def self.const_missing(name) Wrapper.new(name) { const_get(name) } end |
+ (Object) counter(name)
Defines a counter attribute for the model. This attribute can’t be assigned, only incremented or decremented. It will be zero by default.
347 348 349 350 351 352 353 |
# File 'lib/ohm.rb', line 347 def self.counter(name) define_method(name) do read_local(name).to_i end counters << name unless counters.include?(name) end |
+ (Object) counters
528 529 530 |
# File 'lib/ohm.rb', line 528 def self.counters @@counters[self] end |
+ (Object) create(*args)
540 541 542 543 544 |
# File 'lib/ohm.rb', line 540 def self.create(*args) model = new(*args) model.create model end |
+ (Object) define_memoized_method(name, &block)
505 506 507 508 509 510 |
# File 'lib/ohm.rb', line 505 def self.define_memoized_method(name, &block) define_method(name) do instance_variable_get("@#{name}") || instance_variable_set("@#{name}", instance_eval(&block)) end end |
+ (Object) encode(value)
559 560 561 |
# File 'lib/ohm.rb', line 559 def self.encode(value) Base64.encode64(value.to_s).gsub("\n", "") end |
+ (Object) find(hash)
Search across multiple indices and return the intersection of the sets.
554 555 556 557 |
# File 'lib/ohm.rb', line 554 def self.find(hash) raise ArgumentError, "You need to supply a hash with filters. If you want to find by ID, use #{self}[id] instead." unless hash.kind_of?(Hash) all.find(hash) end |
+ (Object) index(att)
Creates an index (a set) that will be used for finding instances.
If you want to find a model instance by some attribute value, then an index for that attribute must exist.
389 390 391 |
# File 'lib/ohm.rb', line 389 def self.index(att) indices << att unless indices.include?(att) end |
+ (Object) indices
536 537 538 |
# File 'lib/ohm.rb', line 536 def self.indices @@indices[self] end |
+ (Object) list(name, model = nil)
Defines a list attribute for the model. It can be accessed only after the model instance is created.
359 360 361 362 |
# File 'lib/ohm.rb', line 359 def self.list(name, model = nil) attr_collection_reader(name, :List, model) collections << name unless collections.include?(name) end |
+ (Object) reference(name, model)
Define a reference to another object.
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'lib/ohm.rb', line 424 def self.reference(name, model) model = Wrapper.wrap(model) reader = :#{name}_id" writer = :#{name}_id=" attribute reader index reader define_memoized_method(name) do model.unwrap[send(reader)] end define_method(:#{name}=") do |value| instance_variable_set("@#{name}", nil) send(writer, value ? value.id : nil) end define_method(writer) do |value| instance_variable_set("@#{name}", nil) write_local(reader, value) end end |
+ (Object) set(name, model = nil)
Defines a set attribute for the model. It can be accessed only after the model instance is created. Sets are recommended when insertion and retrival order is irrelevant, and operations like union, join, and membership checks are important.
369 370 371 372 |
# File 'lib/ohm.rb', line 369 def self.set(name, model = nil) attr_collection_reader(name, :Set, model) collections << name unless collections.include?(name) end |
+ (Object) to_proc
516 517 518 |
# File 'lib/ohm.rb', line 516 def self.to_proc Proc.new { |id| self[id] } end |
+ (Object) to_reference
492 493 494 |
# File 'lib/ohm.rb', line 492 def self.to_reference name.to_s.match(/^(?:.*::)*(.*)$/)[1].gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase.to_sym end |
Instance Method Details
- (Object) ==(other)
684 685 686 687 688 |
# File 'lib/ohm.rb', line 684 def ==(other) other.kind_of?(self.class) && other.key == key rescue MissingID false end |
- (Object) attributes
668 669 670 |
# File 'lib/ohm.rb', line 668 def attributes self.class.attributes end |
- (Object) collections
676 677 678 |
# File 'lib/ohm.rb', line 676 def collections self.class.collections end |
- (Object) counters
672 673 674 |
# File 'lib/ohm.rb', line 672 def counters self.class.counters end |
- (Object) create
572 573 574 575 576 577 578 579 580 581 |
# File 'lib/ohm.rb', line 572 def create return unless valid? initialize_id mutex do create_model_membership write add_to_indices end end |
- (Object) decr(att, count = 1)
Decrement the counter denoted by :att.
622 623 624 |
# File 'lib/ohm.rb', line 622 def decr(att, count = 1) incr(att, -count) end |
- (Object) delete
604 605 606 607 608 609 |
# File 'lib/ohm.rb', line 604 def delete delete_from_indices delete_attributes(collections) unless collections.empty? delete_model_membership self end |
- (Object) incr(att, count = 1)
Increment the counter denoted by :att.
614 615 616 617 |
# File 'lib/ohm.rb', line 614 def incr(att, count = 1) raise ArgumentError, "#{att.inspect} is not a counter." unless counters.include?(att) write_local(att, db.hincrby(key, att, count)) end |
- (Object) indices
680 681 682 |
# File 'lib/ohm.rb', line 680 def indices self.class.indices end |
- (Object) inspect
699 700 701 702 703 704 705 706 707 708 709 710 711 |
# File 'lib/ohm.rb', line 699 def inspect everything = (attributes + collections + counters).map do |att| value = begin send(att) rescue MissingID nil end [att, value.inspect] end "#<#{self.class}:#{new? ? "?" : id} #{everything.map {|e| e.join("=") }.join(" ")}>" end |
- (Object) key(*args) (protected)
734 735 736 |
# File 'lib/ohm.rb', line 734 def key(*args) self.class.key(id, *args) end |
- (Object) mutex
Lock the object before executing the block, and release it once the block is done.
691 692 693 694 695 696 697 |
# File 'lib/ohm.rb', line 691 def mutex lock! yield self ensure unlock! end |
- (Boolean) new?
568 569 570 |
# File 'lib/ohm.rb', line 568 def new? !@id end |
- (Object) save
583 584 585 586 587 588 589 590 591 |
# File 'lib/ohm.rb', line 583 def save return create if new? return unless valid? mutex do write update_indices end end |
- (Object) to_hash
Export the id and errors of the object. The `to_hash` takes the opposite approach of providing all the attributes and instead favors a white listed approach.
657 658 659 660 661 662 |
# File 'lib/ohm.rb', line 657 def to_hash attrs = {} attrs[:id] = id unless new? attrs[:errors] = errors unless errors.empty? attrs end |
- (Object) to_json(*args)
664 665 666 |
# File 'lib/ohm.rb', line 664 def to_json(*args) to_hash.to_json(*args) end |
- (Object) update(attrs)
593 594 595 596 |
# File 'lib/ohm.rb', line 593 def update(attrs) update_attributes(attrs) save end |
- (Object) update_attributes(attrs)
598 599 600 601 602 |
# File 'lib/ohm.rb', line 598 def update_attributes(attrs) attrs.each do |key, value| send(:#{key}=", value) end end |
- (Object) write (protected)
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 |
# File 'lib/ohm.rb', line 738 def write unless attributes.empty? atts = attributes.inject([]) { |ret, att| value = send(att).to_s ret.push(att, value) if not value.empty? ret } db.multi do db.del(key) db.hmset(key, *atts.flatten) if atts.any? end end end |
- (Object) write_remote(att, value) (protected)
754 755 756 757 758 759 760 761 762 |
# File 'lib/ohm.rb', line 754 def write_remote(att, value) write_local(att, value) if value.to_s.empty? db.hdel(key, att) else db.hset(key, att, value) end end |