Module: Ork::Model::Associations

Defined in:
lib/ork/model/associations.rb

Instance Method Summary collapse

Instance Method Details

#collection(name, model, reference = to_reference) ⇒ Object

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


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# 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) ⇒ Object

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


189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# 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) ⇒ Object

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


235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# 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) ⇒ Object

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


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 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) ⇒ Object

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


89
90
91
92
93
94
95
96
97
# 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