blob: 400db6baf13589006d8a11cb2034386dd07bf992 (
plain) (
tree)
|
|
require 'active_support/core_ext/object/blank'
module ActiveRecord
# = Active Record Has Many Through Association
module Associations
class HasManyThroughAssociation < HasManyAssociation #:nodoc:
include ThroughAssociation
alias_method :new, :build
def destroy(*records)
transaction do
delete_records(records.flatten)
super
end
end
# Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been
# loaded and calling collection.size if it has. If it's more likely than not that the collection does
# have a size larger than zero, and you need to fetch that collection afterwards, it'll take one fewer
# SELECT query if you use #length.
def size
if has_cached_counter?
@owner.send(:read_attribute, cached_counter_attribute_name)
elsif loaded?
@target.size
else
count
end
end
protected
def target_reflection_has_associated_record?
if @reflection.through_reflection.macro == :belongs_to && @owner[@reflection.through_reflection.foreign_key].blank?
false
else
true
end
end
def insert_record(record, force = true, validate = true)
if record.new_record?
return false unless save_record(record, force, validate)
end
through_association = @owner.send(@reflection.through_reflection.name)
through_association.create!(construct_join_attributes(record))
end
# TODO - add dependent option support
def delete_records(records)
through_association = @owner.send(@reflection.through_reflection.name)
records.each do |associate|
through_association.where(construct_join_attributes(associate)).delete_all
end
end
def find_target
return [] unless target_reflection_has_associated_record?
scoped.all
end
# NOTE - not sure that we can actually cope with inverses here
def invertible_for?(record)
false
end
end
end
end
|