Class: Pluckr::Reflection::Association

Inherits:
Object
  • Object
show all
Defined in:
lib/pluckr/reflection/association.rb

Overview

Thin wrapper over ActiveRecord association reflection.

Everything Pluckr knows about tables, keys and join direction comes from here - developers never spell out foreign keys in the DSL.

Constant Summary collapse

SINGULAR_MACROS =
%i[belongs_to has_one].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(owner, name, reflection) ⇒ Association

Returns a new instance of Association.



27
28
29
30
31
32
33
# File 'lib/pluckr/reflection/association.rb', line 27

def initialize(owner, name, reflection)
  @owner = owner
  @name = name.to_sym
  @reflection = reflection
  validate_supported!
  freeze
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



12
13
14
# File 'lib/pluckr/reflection/association.rb', line 12

def name
  @name
end

#ownerObject (readonly)

Returns the value of attribute owner.



12
13
14
# File 'lib/pluckr/reflection/association.rb', line 12

def owner
  @owner
end

#reflectionObject (readonly)

Returns the value of attribute reflection.



12
13
14
# File 'lib/pluckr/reflection/association.rb', line 12

def reflection
  @reflection
end

Class Method Details

.for(owner, name) ⇒ Object

Parameters:

  • owner (Class<ActiveRecord::Base>)
  • name (Symbol)

    association name

Raises:



16
17
18
19
20
21
22
23
24
25
# File 'lib/pluckr/reflection/association.rb', line 16

def self.for(owner, name)
  raise MissingSource, "Cannot resolve association `#{name}` without a `source` model" if owner.nil?

  reflection = owner.reflect_on_association(name)
  unless reflection
    raise UnknownAssociation, "#{owner.name} does not have association `#{name}`"
  end

  new(owner, name, reflection)
end

Instance Method Details

#association_keyObject

Column on the association's own table used in the join.



60
61
62
# File 'lib/pluckr/reflection/association.rb', line 60

def association_key
  reflection.join_primary_key.to_s
end

#collection?Boolean

Returns:

  • (Boolean)


55
56
57
# File 'lib/pluckr/reflection/association.rb', line 55

def collection?
  macro == :has_many
end

#join_condition(association_table, owner_table) ⇒ Object

ON clause for owner_table LEFT JOIN association_table.



75
76
77
78
79
80
81
# File 'lib/pluckr/reflection/association.rb', line 75

def join_condition(association_table, owner_table)
  condition = association_table[association_key].eq(owner_table[owner_key])
  return condition unless type_column

  # `has_many :likes, as: :likeable` also matches on likes.likeable_type.
  condition.and(association_table[type_column].eq(owner.polymorphic_name))
end

#klassObject



39
40
41
# File 'lib/pluckr/reflection/association.rb', line 39

def klass
  reflection.klass
end

#macroObject



35
36
37
# File 'lib/pluckr/reflection/association.rb', line 35

def macro
  reflection.macro
end

#owner_keyObject

Column on the owner's table used in the join.



65
66
67
# File 'lib/pluckr/reflection/association.rb', line 65

def owner_key
  reflection.join_foreign_key.to_s
end

#primary_keyObject



47
48
49
# File 'lib/pluckr/reflection/association.rb', line 47

def primary_key
  klass.primary_key
end

#singular?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/pluckr/reflection/association.rb', line 51

def singular?
  SINGULAR_MACROS.include?(macro)
end

#table_nameObject



43
44
45
# File 'lib/pluckr/reflection/association.rb', line 43

def table_name
  klass.table_name
end

#type_columnObject

Column holding the owner's type for has_many/has_one ..., as: :thing.



70
71
72
# File 'lib/pluckr/reflection/association.rb', line 70

def type_column
  reflection.type
end