Edit the migrations:
# db/migrations/20171024081558_create_authors.rb
Hanami::Model.migration do
change do
create_table :authors do
primary_key :id
column :name, String, null: false
column :created_at, DateTime, null: false
column :updated_at, DateTime, null: false
end
end
end
# db/migrations/20171024081617_create_books.rb
Hanami::Model.migration do
create_table :books do
primary_key :id
foreign_key :author_id, :authors, on_delete: :cascade, null: false
column :title, String, null: false
column :created_at, DateTime, null: false
column :updated_at, DateTime, null: false
end
end
end
Now we can prepare the database:
Let’s edit BookRepository
with the following code:
# lib/bookshelf/repositories/book_repository.rb
class BookRepository < Hanami::Repository
associations do
belongs_to :author
end
def find_with_author(id)
aggregate(:author).where(id: id).map_to(Book).one
end
Let’s create a book:
repository = BookRepository.new
book = repository.create(author_id: 1, title: "Hanami")
# => #<Book:0x00007f89ac270118 @attributes={:id=>1, :author_id=>1, :created_at=>2017-10-24 08:25:41 UTC, :updated_at=>2017-10-24 08:25:41 UTC}>
What happens if we load the author with BookRepository#find
?
Because we haven’t the associated records, book.author
is nil
. We can use the method that we have defined on before (#find_with_author
):
book = repository.find_with_author(book.id)
# => #<Book:0x00007fb3f88896a0 @attributes={:id=>1, :author_id=>1, :created_at=>2017-10-24 08:25:41 UTC, :updated_at=>2017-10-24 08:25:41 UTC, :author=>#<Author:0x00007fb3f8888980 @attributes={:id=>1, :name=>"Luca", :created_at=>2017-10-24 08:25:15 UTC, :updated_at=>2017-10-24 08:25:15 UTC}>}>
book.author
# => => #<Author:0x00007fb3f8888980 @attributes={:id=>1, :name=>"Luca", :created_at=>2017-10-24 08:25:15 UTC, :updated_at=>2017-10-24 08:25:15 UTC}>
What if we need to unassociate a book from its author?
Because we declared a foreign key with the , we cannot set author_id
to NULL
or to reference to an unexisting author. This is a mechanism against orphaned records: a book is forced to reference a valid author.
The only way to remove a book from an author is to delete the book record.
repository.delete(book.id)
# => nil