Module: HasSiblings::ClassMethods

Defined in:
lib/has_siblings/class_methods.rb

Instance Method Summary collapse

Instance Method Details

#has_siblings(options = {}) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/has_siblings/class_methods.rb', line 7

def has_siblings(options = {})
  *parents = options.fetch(:through)
  name = options.fetch(:name, "siblings")
  allow_nil = options.fetch(:allow_nil, false)

  reflections = parents.map do |parent|
    reflection = reflect_on_association(parent)
    fail HasSiblings::ReflectionNotFoundError.new(parent, self) if reflection.nil?
    reflection
  end
  where_scopes = reflections.map do |reflection|
    foreign_key = reflection.foreign_key
    foreign_type = reflection.foreign_type

    if reflection.polymorphic?
      "where(#{foreign_key}: #{foreign_key}, #{foreign_type}: #{foreign_type})"
    else
      "where(#{foreign_key}: #{foreign_key})"
    end
  end

  mixin = ActiveRecord.version.to_s >= "4.1" ? generated_association_methods : generated_feature_methods

  mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
    def #{name}
      unless #{allow_nil}
        return self.class.none if [#{parents.join(",")}].any?(&:nil?)
      end

      self.class.#{where_scopes.join(".")}.where.not(id: id)
    end
  CODE
end