Module: ActsAs::ClassMethods

Defined in:
lib/acts_as.rb

Instance Method Summary collapse

Instance Method Details

#acts_as(association, with: [], prefix: [], **options) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/acts_as.rb', line 34

def acts_as(association, with: [], prefix: [], **options)
  belongs_to(association, **options.merge(autosave: true))
  define_method(association) do |*args|
    acted = super(*args) || send("build_#{association}", *args)
    acted.save if persisted? && acted.new_record?
    acted
  end

  if (association_class = (options[:class_name] || association).to_s.camelcase.constantize).table_exists?
    whitelist_and_delegate_fields(association_class, association, prefix, with)
    override_method_missing
  end
end

#acts_as_fieldsObject



48
49
50
# File 'lib/acts_as.rb', line 48

def acts_as_fields
  @acts_as_fields ||= {}
end

#acts_as_fields_match(method) ⇒ Object



52
53
54
55
56
# File 'lib/acts_as.rb', line 52

def acts_as_fields_match(method)
  acts_as_fields.select do |association, fields|
    fields.select { |f| method.to_s.include?(f) }.any?
  end.keys.first
end

#expand_hash_conditions_for_aggregates(attrs) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/acts_as.rb', line 71

def expand_hash_conditions_for_aggregates(attrs)
  attrs = super(attrs)
  expanded_attrs = {}

  attrs.each do |attr, value|
    if (association = acts_as_fields_match(attr)) && !self.columns.map(&:name).include?(attr.to_s)
      expanded_attrs[new.send(association).class.table_name] = { attr => value }
    else
      expanded_attrs[attr] = value
    end
  end
  expanded_attrs
end

#where(opts = :chain, *rest) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/acts_as.rb', line 58

def where(opts = :chain, *rest)
  return self if opts.blank?
  relation = super
  #TODO support nested attribute joins like Guns.where(rebels: {strength: 10}))
  # for now, only first level joins will happen automagically
  if opts.is_a? Hash
    detected_associations = opts.keys.map {|attr| acts_as_fields_match(attr) }
                                     .reject {|attr| attr.nil?}
    return relation.joins(detected_associations) if detected_associations.any?
  end
  relation
end