Hanami Repository Bulk Update

Imagine that your team is tasked to implement a feature that enables a human to
review and publish a list of books. Most of the work has already been done, what
remains is to update the published_at attribute of the subset of books that
were reviewed. To that end you’ll implement a publish method on the
BookRepository that takes the list of reviewed books and updates them.

The feature is a success and your users are happy. It turns out that there are
a lot more bulk operations that users would like to be able to do. For now we
want to enable users to set discounts for books in bulk. Again the UI is already
updated and all we have left to do is implement this in our repository.

# lib/bookshelf/repositories/book_repository.rb# frozen_string_literal: trueclassBookRepository<Hanami::Repositorydefpublish(reviewed_books)update_all(reviewed_books,published_at:Time.now)enddefdiscount(books_on_sale,reduction_rate)# we validate the reduction rate at the controller level, it may even be a# value objectupdate_all(books_on_sale,discount:reduction_rate.to_f)endprivatedefupdate_all(books_to_update,**attribute_value_pairs)books.where(id:books_to_update.map(&:id)).update(**attribute_value_pairs)endend

While it is tempting to just implement the generic update_all method publicly
and use it outside of the repository this flexibility would come at a cost. The
knowledge of what publishing books or granting discounts means would potentially
be spread across our code base.

Instead we define less flexible but intention revealing methods that naturally
attract behaviour pertaining to their responsibility.