Permalink
Browse files

Expands the info about legacy database support (#431)

* Expands the info about legacy database support

* Clean up language

* Using Repository#root
  • Loading branch information...
mereghost authored and AlfonsoUceda committed Aug 6, 2018
1 parent 3885af3 commit 0162b8b04751baa4088c56207c391dbbe4586b99
Showing with 66 additions and 1 deletion.
  1. +66 −1 source/guides/1.1/repositories/overview.md
@@ -201,7 +201,6 @@ While the entity can stay with the basic setup:
class Operator < Hanami::Entity
end
```

---

The entity now gets the mapping we defined in the repository:
@@ -218,6 +217,72 @@ operator = OperatorRepository.new.create(name: "Jane")
# => #<Operator:0x007f8e43cbcea0 @attributes={:id=>1, :name=>"Jane"}>
```

There are few caveats though (as there always are, with legacy databases):

Note that **all** attributes need to be mapped or you will get an error when booting up the application that will look like this:

```ruby
class OperatorRepository < Hanami::Repository
self.relation = :t_operator
mapping do
attribute :id, from: :operator_id
end
end
# => Hanami::Model::Error: key not found: :s_name
```
That happens because the Repository infers the schema for the table and `mapping` only affects the `Hanami::Entity` and commands that operate over it (like `create` and `update`).

A query, on the other hand, will still need to use the original attribute name:

```ruby
class OperatorRepository < Hanami::Repository
self.relation = :t_operator
mapping do
attribute :id, from: :operator_id
attribute :name, from: :s_name
end
def by_name(name)
root.where(s_name: name)
end
end
```

If you want to use the more semantic, aliased names (or with just a subset of attributes) you'll need to define both a `schema` and a `mapping`:

```ruby
class OperatorRepository < Hanami::Repository
self.relation = :t_operator
schema do
attribute :operator_id, Hanami::Model::Sql::Types::Int.meta(primary_key: true, alias: :id)
attribute :s_name, Hanami::Model::Sql::Types::String.meta(alias: :name)
end
mapping do
attribute :id, from: :operator_id
attribute :name, from: :s_name
end
def by_name(name)
t_operator.where(name: name)
end
end
```

Then you can use the aliased names on both queries and entities:

```ruby
operator = OperatorRepository.new.create(name: 'Jane')
# => #<Operator:0x007f8e43cbcea0 @attributes={:id=>1, :name=>"Jane"}>
OperatorRepository.new.by_name('Jane')
# => #<Operator:0x007f3e43cdcea1 @attributes={:id=>1, :name=>"Jane"}>
```

## Count

Count is a concept not generally available to all the databases. SQL databases have it, but others don't.

0 comments on commit 0162b8b

Please sign in to comment.