Module: Associatable

Included in:
Puffs::SQLObject
Defined in:
lib/sql_object/associatable.rb

Overview

Used to map association methods.

Instance Method Summary collapse

Instance Method Details

#assoc_optionsObject



83
84
85
# File 'lib/sql_object/associatable.rb', line 83

def assoc_options
  @assoc_options ||= {}
end

#belongs_to(name, options = {}) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/sql_object/associatable.rb', line 56

def belongs_to(name, options = {})
  options = BelongsToOptions.new(name, options)
  assoc_options[name] = options

  define_method(name) do
    foreign_key_value = send(options.foreign_key)
    return nil if foreign_key_value.nil?

    options.model_class
           .where(options.primary_key => foreign_key_value)
           .first
  end
end

#has_many(name, options = {}) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/sql_object/associatable.rb', line 70

def has_many(name, options = {})
  options = HasManyOptions.new(name, to_s, options)
  assoc_options[name] = options

  define_method(name) do
    target_key_value = send(options.primary_key)
    return nil if target_key_value.nil?
    options.model_class
           .where(options.foreign_key => target_key_value)
           .to_a
  end
end

#has_many_through(name, through_name, source_name) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/sql_object/associatable.rb', line 103

def has_many_through(name, through_name, source_name)
  through_options = assoc_options[through_name]
  define_method(name) do
    through_fk = through_options.foreign_key
    through_class = through_options.model_class
    key_val = send(through_options.primary_key)

    # 2 queries, we could reduce to 1 by writing Puffs::SQLRelation.join.
    through_class.where(through_fk => key_val)
                 .includes(source_name)
                 .load
                 .included_relations
                 .first
                 .to_a
  end
end

#has_one_through(name, through_name, source_name) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/sql_object/associatable.rb', line 87

def has_one_through(name, through_name, source_name)
  through_options = assoc_options[through_name]

  define_method(name) do
    source_options =
      through_options.model_class.assoc_options[source_name]
    through_pk = through_options.primary_key
    key_val = send(through_options.foreign_key)

    source_options.model_class
                  .includes(through_options.model_class)
                  .where(through_pk => key_val)
                  .first
  end
end