Class: ActiveRecord::Associations::HasManyAssociation

Inherits:
AssociationCollection show all
Defined in:
lib/active_record/associations/has_many_association.rb

Overview

:nodoc:

Instance Attribute Summary

Attributes inherited from AssociationProxy

#reflection

Instance Method Summary collapse

Methods inherited from AssociationCollection

#<<, #clear, #create, #delete, #delete_all, #destroy_all, #empty?, #length, #replace, #reset, #size, #to_ary, #uniq

Methods inherited from AssociationProxy

#===, #aliased_table_name, #conditions, #loaded, #loaded?, #proxy_respond_to?, #reload, #reset, #respond_to?, #target, #target=

Constructor Details

#initialize(owner, reflection) ⇒ HasManyAssociation

Returns a new instance of HasManyAssociation.



4
5
6
7
# File 'lib/active_record/associations/has_many_association.rb', line 4

def initialize(owner, reflection)
  super
  construct_sql
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (protected)



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/active_record/associations/has_many_association.rb', line 88

def method_missing(method, *args, &block)
  if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
    super
  else
    @reflection.klass.with_scope(
      :find => {
        :conditions => @finder_sql, 
        :joins      => @join_sql, 
        :readonly   => false
      },
      :create => {
        @reflection.primary_key_name => @owner.id
      }
    ) do
      @reflection.klass.send(method, *args, &block)
    end
  end
end

Instance Method Details

#build(attributes = {}) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
# File 'lib/active_record/associations/has_many_association.rb', line 9

def build(attributes = {})
  if attributes.is_a?(Array)
    attributes.collect { |attr| build(attr) }
  else
    load_target
    record = @reflection.klass.new(attributes)
    set_belongs_to_association_for(record)
    @target << record
    record
  end
end

#count(runtime_conditions = nil) ⇒ Object

Count the number of associated records. All arguments are optional.



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/active_record/associations/has_many_association.rb', line 39

def count(runtime_conditions = nil)
  if @reflection.options[:counter_sql]
    @reflection.klass.count_by_sql(@counter_sql)
  elsif @reflection.options[:finder_sql]
    @reflection.klass.count_by_sql(@finder_sql)
  else
    sql = @finder_sql
    sql += " AND (#{sanitize_sql(runtime_conditions)})" if runtime_conditions
    @reflection.klass.count(sql)
  end
end

#find(*args) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/active_record/associations/has_many_association.rb', line 51

def find(*args)
  options = Base.send(:extract_options_from_args!, args)

  # If using a custom finder_sql, scan the entire collection.
  if @reflection.options[:finder_sql]
    expects_array = args.first.kind_of?(Array)
    ids = args.flatten.compact.uniq

    if ids.size == 1
      id = ids.first
      record = load_target.detect { |record| id == record.id }
      expects_array ? [ record ] : record
    else
      load_target.select { |record| ids.include?(record.id) }
    end
  else
    conditions = "#{@finder_sql}"
    if sanitized_conditions = sanitize_sql(options[:conditions])
      conditions << " AND (#{sanitized_conditions})"
    end
    options[:conditions] = conditions

    if options[:order] && @reflection.options[:order]
      options[:order] = "#{options[:order]}, #{@reflection.options[:order]}"
    elsif @reflection.options[:order]
      options[:order] = @reflection.options[:order]
    end

    merge_options_from_reflection!(options)

    # Pass through args exactly as we received them.
    args << options
    @reflection.klass.find(*args)
  end
end

#find_all(runtime_conditions = nil, orderings = nil, limit = nil, joins = nil) ⇒ Object

DEPRECATED.



22
23
24
25
26
27
28
29
30
31
# File 'lib/active_record/associations/has_many_association.rb', line 22

def find_all(runtime_conditions = nil, orderings = nil, limit = nil, joins = nil)
  if @reflection.options[:finder_sql]
    @reflection.klass.find_by_sql(@finder_sql)
  else
    conditions = @finder_sql
    conditions += " AND (#{sanitize_sql(runtime_conditions)})" if runtime_conditions
    orderings ||= @reflection.options[:order]
    @reflection.klass.find_all(conditions, orderings, limit, joins)
  end
end

#find_first(conditions = nil, orderings = nil) ⇒ Object

DEPRECATED. Find the first associated record. All arguments are optional.



34
35
36
# File 'lib/active_record/associations/has_many_association.rb', line 34

def find_first(conditions = nil, orderings = nil)
  find_all(conditions, orderings, 1).first
end