module Ork::Model::Associations

Public Instance Methods

collection(name, model, reference = to_reference) click to toggle source

A macro for defining a method which basically does a find.

Example:

class Post
  include Ork::Document

  reference :user, :User
end

class User
  include Ork::Document

  collection :posts, :Post
end

# is the same as

class User
  include Ork::Document

  attribute posts_ids

  def posts
    Post.all(self.posts_ids)
  end

  def posts_add(post)
    self.posts_ids << post.id
  end
end
# File lib/ork/model/associations.rb, line 130
def collection(name, model, reference = to_reference)
  reader = :"#{name}_ids"

  attribute reader, accessors: :reader

  define_method(:"#{name}_ids=") do |value|
    @_memo.delete(name)
    @attributes[reader] = value
  end

  define_method(name) do
    return [] if self.id.nil?
    @_memo[name] ||= begin
                       model = Ork::Utils.const(self.class, model)
                       model.all(@attributes[reader].to_a)
                     end
  end

  define_method(:"#{name}_add") do |object|
    assert_valid_class object, model

    @attributes[reader] = Array(@attributes[reader]) << object.id
    @_memo[name] << object if @_memo[name]
  end

  define_method(:"#{name}_remove") do |object|
    assert_valid_class object, model

    @_memo[name].delete(object) if @_memo[name]
    @attributes[reader].delete(object.id) and object if @attributes[reader]
  end
end
embed(name, model) click to toggle source

A macro for defining an attribute, and the accessors for a given model.

Example:

class Post
  include Ork::Document

  embed :author, :Author
end

# It's the same as:

class Post
  include Ork::Document

  def author
    @embedding[:author]
  end

  def author=(author)
    @embedding[:author] = author
    author.__parent = self
  end
end
# File lib/ork/model/associations.rb, line 189
def embed(name, model)
  embedding << name unless embedding.include?(name)

  define_method(name) do
    return nil unless @embedding.has_key? name
    @_memo[name] ||= begin
                       model = Ork::Utils.const(self.class, model)
                       new_embedded model, @embedding[name]
                     end
  end

  define_method(:"#{name}=") do |object|
    assert_embeddable object

    @embedding[name] = object.attributes
    object.__parent = self

    @_memo[name] = object
  end
end
embed_collection(name, model) click to toggle source

A macro for find embedded objects of the same type, massive assign and syntactic sugar for add an object to the collection.

Example:

class Post
  include Ork::Document

  embed_collection :authors, :Author
end

# It's the same as:

class Post
  include Ork::Document

  def authors
    # An array of authors
  end

  def authors_add(author)
    # Add an author to the embed collection
  end
end
# File lib/ork/model/associations.rb, line 235
def embed_collection(name, model)
  embedding << name unless embedding.include?(name)

  define_method(name) do
    return [] unless @embedding.has_key? name

    @_memo[name] ||= begin
                       model = Ork::Utils.const(self.class, model)
                       @embedding[name].map do |atts|
                         new_embedded model, atts
                       end
                     end
  end

  define_method(:"#{name}_add") do |object|
    assert_embeddable object

    object.__parent = self
    @_memo[name] << object if @_memo[name]
    @embedding[name] = Array(@embedding[name]) << object.attributes
  end

  define_method(:"#{name}_remove") do |object|
    assert_embeddable object

    object.__parent = nil
    @_memo[name].delete(object) if @_memo[name]
    @embedding[name].delete(object.attributes) and object if @embedding[name]
  end
end
reference(name, model) click to toggle source

A macro for defining an attribute, an index, and an accessor for a given model.

Example:

class Post
  include Ork::Document

  reference :user, :User
end

# It's the same as:

class Post
  include Ork::Document

  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
# File lib/ork/model/associations.rb, line 37
def reference(name, model)
  reader = :"#{name}_id"
  writer = :"#{name}_id="

  attribute reader, accessors: :reader
  index reader

  define_method(writer) do |value|
    @_memo.delete(name)
    @attributes[reader] = value
  end

  define_method(:"#{name}=") do |object|
    assert_valid_class object, model

    send(writer, object ? object.id : nil)
    @_memo[name] = object
  end

  define_method(name) do
    @_memo[name] ||= begin
                       model = Ork::Utils.const(self.class, model)
                       model[send(reader)]
                     end
  end
end
referenced(name, model, reference = to_reference) click to toggle source

A macro for defining a method which basically does a find.

Example:

class Post
  include Ork::Document

  reference :user, :User
end

class User
  include Ork::Document

  referenced :post, :Post
end

# is the same as

class User
  include Ork::Document

  def post
    Post.find(:user_id => self.id)
  end
end
# File lib/ork/model/associations.rb, line 89
def referenced(name, model, reference = to_reference)
  define_method name do
    return nil if self.id.nil?
    @_memo[name] ||= begin
                       model = Ork::Utils.const(self.class, model)
                       model.find(:"#{reference}_id", self.id).first
                     end
  end
end

Private Instance Methods

to_reference() click to toggle source
# File lib/ork/model/associations.rb, line 268
def to_reference
  name.to_s.
    match(/^(?:.*::)*(.*)$/)[1].
    gsub(/([a-z\d])([A-Z])/, '\1_\2').
    downcase.to_sym
end