Class: DataMapper::Associations::HasAndBelongsToManyAssociation::Set

Inherits:
Reference
  • Object
show all
Includes:
Enumerable
Defined in:
lib/data_mapper/associations/has_and_belongs_to_many_association.rb

Instance Method Summary collapse

Methods inherited from Reference

#association

Constructor Details

#initialize(*args) ⇒ Set

Returns a new instance of Set.



143
144
145
146
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 143

def initialize(*args)
  super
  @new_members = false
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args, &block) ⇒ Object



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 253

def method_missing(symbol, *args, &block)
  if entries.respond_to?(symbol)
    entries.send(symbol, *args, &block)
  elsif association.associated_table.associations.any? { |assoc| assoc.name == symbol }
    results = []
    each do |item|
      unless (val = item.send(symbol)).blank?
        results << (val.is_a?(Enumerable) ? val.entries : val)
      end
    end
    results.flatten
  else
    super
  end
end

Instance Method Details

#<<(member) ⇒ Object



225
226
227
228
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 225

def <<(member)
  @new_members = true
  entries << member unless member.nil?
end

#[](key) ⇒ Object



161
162
163
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 161

def [](key)
  entries[key]
end

#clearObject



230
231
232
233
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 230

def clear
  @new_members = true
  @entries = []
end

#countObject



157
158
159
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 157

def count
  entries.size
end

#delete(member) ⇒ Object



240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 240

def delete(member)
  @new_members = true
  if entries.delete(member)
    @instance.database_context.adapter.connection do |db|
      command = db.create_command(association.to_delete_member_sql)
      command.execute_non_query(@instance.key, member.key)
    end
    member
  else
    nil
  end
end

#dirty?Boolean

Returns:

  • (Boolean)


169
170
171
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 169

def dirty?
  @new_members || (@entries && @entries.any? { |item| item != @instance && item.dirty? })
end

#eachObject



148
149
150
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 148

def each
  entries.each { |item| yield item }
end

#empty?Boolean

Returns:

  • (Boolean)


165
166
167
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 165

def empty?
  entries.empty?
end

#entriesObject



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 269

def entries
  @entries || @entries = begin

    if @instance.loaded_set.nil?
      []
    else
      
      associated_items = Hash.new { |h,k| h[k] = [] }
      left_key_index = nil
      association_constant = association.constant
      left_foreign_key = association.left_foreign_key
      
      matcher = lambda do |instance,columns,row|
        
        # Locate the column for the left-key.
        unless left_key_index
          columns.each_with_index do |column, index|
            if column.name == association.left_foreign_key.name
              left_key_index = index
              break
            end
          end
        end
        
        if instance.kind_of?(association_constant)
          associated_items[left_foreign_key.type_cast_value(row[left_key_index])] << instance
        end
      end
        
      @instance.database_context.all(association.constant,
        left_foreign_key => @instance.loaded_set.map(&:key),
        :shallow_include => association.foreign_name,
        :intercept_load => matcher
      )
      
      # do stsuff with associated_items hash.
      setter_method = "#{@association_name}=".to_sym
      
      @instance.loaded_set.each do |entry|
        entry.send(setter_method, associated_items[entry.key])
      end # @instance.loaded_set.each
      
      @entries              
    end
  end
end

#inspectObject



320
321
322
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 320

def inspect
  entries.inspect
end

#reload!Object



235
236
237
238
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 235

def reload!
  @new_members = false
  @entries = nil
end

#save_without_validation(database_context) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 177

def save_without_validation(database_context)
  unless @entries.nil?
    
    if @new_members || dirty?
      adapter = @instance.database_context.adapter
      
      adapter.connection do |db|
        command = db.create_command(association.to_delete_sql)
        command.execute_non_query(@instance.key)
      end
      
      unless @entries.empty?
        if adapter.batch_insertable?
          sql = association.to_insert_sql
          values = []
          keys = []
      
          @entries.each do |member|
            adapter.save_without_validation(database_context, member)
            values << "(?, ?)"
            keys << @instance.key << member.key
          end
    
          adapter.connection do |db|
            command = db.create_command(sql << ' ' << values.join(', '))
            command.execute_non_query(*keys)
          end
      
        else # adapter doesn't support batch inserts...
          @entries.each do |member|
            adapter.save_without_validation(database_context, member)          
          end
      
          # Just to keep the same flow as the batch-insert mode.
          @entries.each do |member|
            adapter.connection do |db|
              command = db.create_command("#{association.to_insert_sql} (?, ?)")
              command.execute_non_query(@instance.key, member.key)
            end
          end
        end # if adapter.batch_insertable?
      end # unless @entries.empty?
      
      @new_members = false
    end # if @new_members || dirty?
  end
end

#set(results) ⇒ Object



316
317
318
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 316

def set(results)
  @entries = results
end

#sizeObject Also known as: length



152
153
154
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 152

def size
  entries.size
end

#validate_recursively(event, cleared) ⇒ Object



173
174
175
# File 'lib/data_mapper/associations/has_and_belongs_to_many_association.rb', line 173

def validate_recursively(event, cleared)
  @entries.blank? || @entries.all? { |item| cleared.include?(item) || item.validate_recursively(event, cleared) }
end