module ActsAs::ClassMethods

Public Instance Methods

acts_as(association, with: [], prefix: [], **options) click to toggle source
Calls superclass method
# File lib/acts_as.rb, line 36
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_fields() click to toggle source
# File lib/acts_as.rb, line 50
def acts_as_fields
  @acts_as_fields ||= {}
end
acts_as_fields_match(method) click to toggle source
# File lib/acts_as.rb, line 54
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) click to toggle source
Calls superclass method
# File lib/acts_as.rb, line 72
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) click to toggle source
Calls superclass method
# File lib/acts_as.rb, line 60
def where(opts = :chain, *rest)
  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

Private Instance Methods

override_method_missing() click to toggle source
Calls superclass method
# File lib/acts_as.rb, line 88
def override_method_missing
  define_method :method_missing do |method, *args, &block|
    if acts_as_field_match?(method)
      send(@association_match).send(method, *args, &block)
    else
      super(method, *args, &block)
    end
  end

  define_method :respond_to? do |method, *args, &block|
    acts_as_field_match?(method) || super(method, *args, &block)
  end
end
whitelist_and_delegate_fields(association_class, one_association, prefix, with) click to toggle source
# File lib/acts_as.rb, line 102
def whitelist_and_delegate_fields(association_class, one_association, prefix, with)
  association_fields = association_class.columns.map(&:name) - PREFIX - prefix + with

  delegate(*(association_fields + association_fields.map { |field| "#{field}=" }), to: one_association)
  delegate(*(prefix + prefix.map { |field| "#{field}=" }), to: one_association, prefix: true)

  acts_as_fields[one_association] = association_fields + prefix
end