Class: Slick::Database::Row

Inherits:
Object show all
Extended by:
Registry
Defined in:
lib/slick/database/row.rb

Class Attribute Summary collapse

Attributes included from Registry

#name

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Registry

create, for, register, registered?, registered_classes

Constructor Details

#initialize(database, fields = {}) ⇒ Row

Returns a new instance of Row.



37
38
39
40
41
42
# File 'lib/slick/database/row.rb', line 37

def initialize(database, fields = {})
    @database = database
    @fields = fields
    @altered_fields = {}
    @update_level = 0
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/slick/database/row.rb', line 79

def method_missing(name, *args, &block)
    if args.length == 1 && matches = name.match(/\A(.+)=\z/)
        if _column_names.include?(matches[1])
            @altered_fields[matches[1]] = args.first if @fields[matches[1]] != args.first
            update if @update_level == 0
        else
            raise "No such column '#{matches[1]} exists for table '#{self.class.name.pluralize}'"
        end
    elsif args.length == 0
        name = name.to_s
        if _column_names.include?(name)
            if @altered_fields.key?(name)
                @altered_fields[name]
            else
                @fields[name]
            end
        else
            raise "No such column '#{name}' exists for table '#{self.class.name.pluralize}'"
        end
    else
        super
    end
end

Class Attribute Details

.table_classObject

Returns the value of attribute table_class.



8
9
10
# File 'lib/slick/database/row.rb', line 8

def table_class
  @table_class
end

Class Method Details

.belongs_to(name, *args, &block) ⇒ Object



30
31
32
33
# File 'lib/slick/database/row.rb', line 30

def belongs_to(name, *args, &block)
    table_class.belongs_to(name, *args, &block)
    class_eval("def #{name}; self.class.table_class.new(@database).id_eq(id).#{name}.first; end")
end

.has_many(name, *args, &block) ⇒ Object



20
21
22
23
# File 'lib/slick/database/row.rb', line 20

def has_many(name, *args, &block)
   table_class.has_many(name, *args, &block)
   class_eval("def #{name}; self.class.table_class.new(@database).id_eq(id).#{name}; end")
end

.has_one(name, *args, &block) ⇒ Object



25
26
27
28
# File 'lib/slick/database/row.rb', line 25

def has_one(name, *args, &block)
    table_class.has_one(name, *args, &block)
    class_eval("def #{name}; self.class.table_class.new(@database).id_eq(id).#{name}.first; end")
end

.register(name, options = {}) ⇒ Object



10
11
12
13
14
15
16
17
18
# File 'lib/slick/database/row.rb', line 10

def register(name, options = {})
    if options[:abstract]
        union_class = Slick::Database::Union.for(name.pluralize, :register_if_not_exists => true)
        union_class.table_classes << table_class if !union_class.table_classes.include?(table_class)
    else
        super(name)
        @table_class = Slick::Database::Table.for(name.pluralize, :register_if_not_exists => true)
    end
end

Instance Method Details

#_column_namesObject



123
124
125
# File 'lib/slick/database/row.rb', line 123

def _column_names
    @_column_names ||= Slick::Database::Table.create(self.class.name.pluralize, @database).columns.keys
end

#_generate_insert_sqlObject



103
104
105
106
107
108
109
# File 'lib/slick/database/row.rb', line 103

def _generate_insert_sql
    out = []
    out << ['insert into ?', self.class.name.pluralize.to_sym]
    out << ["(#{@altered_fields.keys.map{'?'}.join(', ')})", @altered_fields.keys.map{|name| name.to_sym}]
    out << ["values(#{@altered_fields.keys.map{'?'}.join(', ')})", @altered_fields.values]
    out
end

#_generate_update_sqlObject



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/slick/database/row.rb', line 111

def _generate_update_sql
    out = []
    out << ['update ? ', self.class.name.pluralize.to_sym]
    out << ['set']
    out << @altered_fields.keys.map{'? = ?'}.join(', ')
    @altered_fields.each do |name, value|
        out << [name.to_sym, value]
    end
    out << ['where id = ?', @fields['id']]
    out
end

#deleteObject



75
76
77
# File 'lib/slick/database/row.rb', line 75

def delete
    @database.run('delete from ? where id = ?', self.class.name.pluralize.to_sym, id)
end

#id=(value) ⇒ Object



48
49
50
# File 'lib/slick/database/row.rb', line 48

def id=(value)
    raise "Id fields can't be set directly on a row"
end

#inspectObject



44
45
46
# File 'lib/slick/database/row.rb', line 44

def inspect
    @fields
end

#update(fields = {}, &block) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/slick/database/row.rb', line 52

def update(fields = {}, &block)
    @update_level += 1
    fields.each{ |name, value| send("#{name}=", value) }

    if block
        if block.arity > 0
            block.call(self)
        else
           instance_eval(&block) 
        end
    end
    @update_level -=1

    if @update_level == 0 && @altered_fields.count > 0
        if @fields['id'].nil?
            @database.run(_generate_insert_sql())
        else
            @database.run(_generate_update_sql())
        end
    end
    self
end