Class: Ohm::Model::Wrapper

Inherits:
BasicObject
Defined in:
lib/ohm.rb

Overview

Wraps a model name for lazy evaluation.

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Wrapper) initialize(name, &block)

Allows you to use a constant even before it is defined. This solves the issue of having to require inter-project dependencies in a very simple and “magic-free” manner.

Example of how it was done before Wrapper existed:

  require "./app/models/user"
  require "./app/models/comment"

  class Post < Ohm::Model
    reference :author, User
    list :comments, Comment
  end

Now, you can simply do the following:

  class Post < Ohm::Model
    reference :author, User
    list :comments, Comment
  end

Examples:

module Commenting
  def self.included(base)
    base.list :comments, Ohm::Model::Wrapper.new(:Comment) {
      Object.const_get(:Comment)
    }
  end
end

# In your classes:
class Post < Ohm::Model
  include Commenting
end

class Comment < Ohm::Model
end

p = Post.create
p.comments.empty?
# => true

p.comments.push(Comment.create)
p.comments.size == 1
# => true

Parameters:

  • name (Symbol, String)

    Canonical name of wrapped class.

  • block (#to_proc)

    Closure for getting the name of the constant.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/ohm.rb', line 208

def initialize(name, &block)
  @name = name
  @caller = ::Kernel.caller[2]
  @block = block

  class << self
    def method_missing(method_id, *args)
      ::Kernel.raise(
        ::NoMethodError,
        "You tried to call %s#%s, but %s is not defined on %s" % [
          @name, method_id, @name, @caller
        ]
      )
    end
  end
end

Class Method Details

+ (Object) wrap(object)

Used as a convenience for wrapping an existing constant into a wrapper object.

This is used extensively within the library for points where a user defined class (e.g. Post, User, Comment) is expected.

You can also use this if you need to do uncommon things, such as creating your own Set, List, etc.

(NOTE: Keep in mind that the following code is given only as an educational example, and is in no way prescribed as good design.)

  class User < Ohm::Model
  end

  User.create(:id => "1001")

  Ohm.redis.sadd("myset", 1001)

  key = Ohm::Key.new("myset", Ohm.redis)
  set = Ohm::Model::Set.new(key, Ohm::Model::Wrapper.wrap(User))

  [User[1001]] == set.all.to_a
  # => true

See Also:



251
252
253
# File 'lib/ohm.rb', line 251

def self.wrap(object)
  object.class == self ? object : new(object.inspect) { object }
end

Instance Method Details

- (Wrapper) class

Since Ohm::Model::Wrapper is a subclass of BasicObject we have to manually declare this.

Returns:



266
267
268
# File 'lib/ohm.rb', line 266

def class
  Wrapper
end

- (String) inspect

A string describing this lazy object.

Returns:

  • (String)

    A string describing this lazy object.



271
272
273
# File 'lib/ohm.rb', line 271

def inspect
  "<Wrapper for #{@name} (in #{@caller})>"
end

- (Class) unwrap

Evaluates the passed block in #initialize.

Returns:

  • (Class)

    The wrapped class.



258
259
260
# File 'lib/ohm.rb', line 258

def unwrap
  @block.call
end