Class: Flounder::Entity

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Enumerable
Defined in:
lib/flounder/entity.rb

Overview

An entity corresponds to a table in the database. On top of its table name, an entity will know its code name (plural) and its singular name, what to call a single row returned from this entity.

An entity is not a model. In fact, it is what you need to completely hand-roll your models, without being the model itself.

Entities are mainly used to start a query via one of the query initiators. Almost all of the chain methods on the Query object can be used here as well - they will return a query object. Entities, like queries, can be used as enumerables.

Example:

foo = domain.entity(:plural, :singular, 'table_name')

foo.all # SELECT * FROM table_name
foo.where(id: 1).first  # SELECT * FROM table_name WHERE "table_name"."id" = 1

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(domain, plural, singular, table_name) ⇒ Entity

Returns a new instance of Entity.



27
28
29
30
31
32
33
34
35
36
# File 'lib/flounder/entity.rb', line 27

def initialize domain, plural, singular, table_name
  @domain = domain
  @name = plural
  @singular = singular
  @table_name = table_name
  @columns_hash = nil
  @relations = {} # name -> relation

  @table = Arel::Table.new(table_name)
end

Instance Attribute Details

#domainDomain (readonly)

Returns Domain this entity is defined in.

Returns:

  • (Domain)

    Domain this entity is defined in.



39
40
41
# File 'lib/flounder/entity.rb', line 39

def domain
  @domain
end

#nameSymbol (readonly) Also known as: plural

Returns Name of the entity in plural form.

Returns:

  • (Symbol)

    Name of the entity in plural form.



42
43
44
# File 'lib/flounder/entity.rb', line 42

def name
  @name
end

#relationsArray

Returns relations that this entity has to other entities.

Returns:

  • (Array)

    relations that this entity has to other entities



56
57
58
# File 'lib/flounder/entity.rb', line 56

def relations
  @relations
end

#singularSymbol (readonly)

Returns Name of the entity in singular form.

Returns:

  • (Symbol)

    Name of the entity in singular form.



48
49
50
# File 'lib/flounder/entity.rb', line 48

def singular
  @singular
end

#tableArel::Table (readonly)

Returns Arel table that underlies this entity.

Returns:

  • (Arel::Table)

    Arel table that underlies this entity.



51
52
53
# File 'lib/flounder/entity.rb', line 51

def table
  @table
end

#table_nameString (readonly)

Returns Name of the table that underlies this entity.

Returns:

  • (String)

    Name of the table that underlies this entity.



53
54
55
# File 'lib/flounder/entity.rb', line 53

def table_name
  @table_name
end

Instance Method Details

#[](name) ⇒ Field

Returns Field with name of the entity.

Returns:

  • (Field)

    Field with name of the entity.



63
64
65
# File 'lib/flounder/entity.rb', line 63

def [] name
  Field.new(self, name, table[name])
end

#add_relationship(type, name, entity_ref = nil, **join_conditions) ⇒ Object

Raises:

  • (ArgumentError)


104
105
106
107
108
109
# File 'lib/flounder/entity.rb', line 104

def add_relationship type, name, entity_ref=nil, **join_conditions
  raise ArgumentError, "Must have join conditions." if join_conditions.empty?
  
  relations[name] = Relation.new(
    domain, type, name, entity_ref||name, join_conditions)
end

#as(plural, singular) ⇒ Object

Temporarily creates a new entity that is available as if it was declared with the given plural and singular, but referencing to the same underlying relation.



150
151
152
# File 'lib/flounder/entity.rb', line 150

def as plural, singular
  EntityAlias.new(self, plural, singular)
end

#belongs_to(*a) ⇒ Object

Adds a relationship where one record on the other entity corresponds to possibly many on our side.

Example:

domain.entity :foos, :foo, 'foo' do |foo|
  foo.belongs_to :bar, :bar_id => :id
end

You can also explicitly name the relationship instead of going through the singular name of the other entity:

Example:

domain.entity :foos, :foo, 'foo' do |foo|
  foo.belongs_to :bar_stuff, :bar, :bar_id => :id
end


100
101
102
# File 'lib/flounder/entity.rb', line 100

def belongs_to *a
  add_relationship :belongs_to, *a
end

#column_namesObject



161
162
163
# File 'lib/flounder/entity.rb', line 161

def column_names
  columns_hash.keys
end

#columns_hashObject



154
155
156
157
158
159
160
# File 'lib/flounder/entity.rb', line 154

def columns_hash
  @columns_hash ||= begin
    domain.connection_pool.with_connection do |conn|
      conn.columns_hash(table_name)
    end
  end      
end

#cond(*conditions) ⇒ Object

Builds a condition part or a general SQL expression.

entity.cond(a: 1)


115
116
117
118
# File 'lib/flounder/entity.rb', line 115

def cond *conditions
  builder = Expression::Builder.new(domain)
  builder.interpret_conditions(self, conditions)
end

#deleteObject



142
143
144
# File 'lib/flounder/entity.rb', line 142

def delete 
  Query::Delete.new(domain, self)
end

#each(&block) ⇒ Object



182
183
184
# File 'lib/flounder/entity.rb', line 182

def each &block
  all.each &block
end

#fields(*names) ⇒ Object



66
67
68
# File 'lib/flounder/entity.rb', line 66

def fields *names
  (names.empty? ? column_names : names).map { |name| self[name] }
end

#has_many(*a) ⇒ Object

Adds a relationship where many records on the other entity correspond to this one.



80
81
82
# File 'lib/flounder/entity.rb', line 80

def has_many *a
  add_relationship :has_many, *a
end

#insert(hash) ⇒ Object



132
133
134
135
# File 'lib/flounder/entity.rb', line 132

def insert hash
  Query::Insert.new(domain, self).tap { |q| 
    q.row(hash) }
end

#inspectObject Also known as: to_s



70
71
72
# File 'lib/flounder/entity.rb', line 70

def inspect
  "<Flounder/Entity #{name}(#{table_name})>"
end

#selectQuery::Select

Starts a new select query and yields it to the block. Note that you don’t need to call this method to obtain a select query - any of the methods on Query::Select should work on the entity and return a new query object.

Returns:



126
127
128
129
130
# File 'lib/flounder/entity.rb', line 126

def select
  Query::Select.new(domain, self).tap { |q| 
    yield q if block_given? 
  }
end

#update(hash) ⇒ Object



137
138
139
140
# File 'lib/flounder/entity.rb', line 137

def update hash
  Query::Update.new(domain, self).tap { |u|
    u.set(hash) }
end