Module: Associatable

Included in:
ActiveLeopard::Base
Defined in:
lib/activeleopard/modules/associatable.rb

Instance Method Summary collapse

Instance Method Details

#assoc_optionsObject



29
30
31
# File 'lib/activeleopard/modules/associatable.rb', line 29

def assoc_options
  @assoc_options ||= {}
end

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



2
3
4
5
6
7
8
9
10
11
12
13
14
15
# File 'lib/activeleopard/modules/associatable.rb', line 2

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

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

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

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



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/activeleopard/modules/associatable.rb', line 17

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

  define_method(name) do
    primary_key_val = self.send(options.primary_key)

    options.model_class
      .where(options.foreign_key => primary_key_val)
  end
end

#has_many_through(name, through_name, source_name) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/activeleopard/modules/associatable.rb', line 61

def has_many_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_table = through_options.model_class.table_name
    source_table = source_options.model_class.table_name

    data = DBConnection.execute(<<-SQL)
      SELECT
        #{source_table}.*
      FROM
        #{through_table}
      JOIN
        #{source_table}
        ON #{through_table}.#{source_options.primary_key} =
            #{source_table}.#{source_options.foreign_key}
      WHERE
        #{through_table}.#{through_options.foreign_key} =
              #{self.id}
    SQL

    data.map { |datum| source_options.model_class.new(datum) }
  end
end

#has_one_through(name, through_name, source_name) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/activeleopard/modules/associatable.rb', line 33

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_table = through_options.model_class.table_name
    source_table = source_options.model_class.table_name

    datum = DBConnection.execute(<<-SQL).first
      SELECT
        #{source_table}.*
      FROM
        #{through_table}
      JOIN
        #{source_table}
      ON
        #{through_table}.#{source_options.foreign_key} =
            #{source_table}.#{source_options.primary_key}
      WHERE
        #{through_table}.#{through_options.primary_key} =
                #{self.send(through_options.foreign_key)}
    SQL

    source_options.model_class.new(datum)
  end
end