Add actions to support books' editions.

dev
KKlochko 4 months ago
parent a7c6d6770c
commit 74f4e99957

@ -3,7 +3,21 @@ defmodule DecentralisedBookIndex.Metadata do
otp_app: :decentralised_book_index otp_app: :decentralised_book_index
resources do resources do
resource DecentralisedBookIndex.Metadata.Book resource DecentralisedBookIndex.Metadata.Book do
define :create_book,
action: :create,
args: [:title, :isbn, :description, {:optional, :book_editions_registry_id}]
define :add_book_to_related_editions_registry,
action: :add_book_to_related_editions_registry,
args: [:title, :isbn, :description, :related_book_id]
define :list_books, action: :read
define :get_book_by_id, args: [:id], action: :by_id
define :get_book_alternative_editions, args: [:book], action: :get_alternative_editions
define :update_book, action: :update
define :destroy_book, action: :destroy
end
resource DecentralisedBookIndex.Metadata.Author do resource DecentralisedBookIndex.Metadata.Author do
define :create_author, define :create_author,
@ -31,6 +45,12 @@ defmodule DecentralisedBookIndex.Metadata do
define :destroy_author_alias_registry, action: :destroy define :destroy_author_alias_registry, action: :destroy
end end
resource DecentralisedBookIndex.Metadata.BookEditionsRegistry resource DecentralisedBookIndex.Metadata.BookEditionsRegistry do
define :create_book_editions_registry, action: :create
define :list_book_editions_registries, action: :read
define :get_book_editions_registry_by_id, args: [:id], action: :by_id
define :update_book_editions_registry, action: :update
define :destroy_book_editions_registry, action: :destroy
end
end end
end end

@ -4,13 +4,70 @@ defmodule DecentralisedBookIndex.Metadata.Book do
domain: DecentralisedBookIndex.Metadata, domain: DecentralisedBookIndex.Metadata,
data_layer: AshPostgres.DataLayer data_layer: AshPostgres.DataLayer
require Ash.Query
postgres do postgres do
table "books" table "books"
repo DecentralisedBookIndex.Repo repo DecentralisedBookIndex.Repo
end end
actions do actions do
defaults [:read] defaults [:read, :update, :destroy]
create :create do
primary? true
accept [:title, :isbn, :description, :book_editions_registry_id]
change fn changeset, _ ->
registry_id = Ash.Changeset.get_attribute(changeset, :book_editions_registry_id)
if registry_id == nil do
{:ok, registry} = DecentralisedBookIndex.Metadata.create_book_editions_registry()
Ash.Changeset.force_change_attribute(changeset, :book_editions_registry_id, registry.id)
else
changeset
end
end
end
create :add_book_to_related_editions_registry do
accept [:title, :isbn, :description]
argument :related_book_id, :uuid do
allow_nil? false
end
change fn changeset, context ->
related_book_id = changeset.arguments.related_book_id
if related_book_id == nil do
Ash.Changeset.add_error(changeset, :related_book_id, "Related book is empty")
else
{:ok, related_book} = DecentralisedBookIndex.Metadata.get_book_by_id(related_book_id)
Ash.Changeset.force_change_attribute(changeset, :book_editions_registry_id, related_book.book_editions_registry_id)
end
end
end
read :by_id do
argument :id, :uuid, allow_nil?: false
get? true
filter expr(id == ^arg(:id))
end
read :get_alternative_editions do
argument :book, :struct, allow_nil?: false
prepare fn query, context ->
book = query.arguments.book
DecentralisedBookIndex.Metadata.Book
|> Ash.Query.filter(book_editions_registry_id == ^book.book_editions_registry_id
and id != ^book.id)
end
end
end end
attributes do attributes do

@ -0,0 +1,50 @@
defmodule DecentralisedBookIndex.Metadata.BookTest do
use DecentralisedBookIndex.DataCase, async: true
alias DecentralisedBookIndex.Metadata
describe "books and registries relationship" do
test "a new book get new registry by default" do
assert {:ok, book} = Metadata.create_book("Book", "1234567890", "An description")
assert book.book_editions_registry_id != nil
end
test "a new book belongs to a registry if specified" do
assert {:ok, registry} = Metadata.create_book_editions_registry()
assert {:ok, book} = Metadata.create_book("Book", "1234567890", "An description", registry.id)
assert book.book_editions_registry_id == registry.id
end
test "a new book to a registry via a related book record" do
{:ok, related_book} = Metadata.create_book("Book", "1234567890", "An description")
assert {:ok, book} =
Metadata.add_book_to_related_editions_registry("Book2", "1234567891", "An description2", related_book.id)
assert related_book.book_editions_registry_id == book.book_editions_registry_id
end
test "a new book to a registry via a empty related book record" do
assert {:error, _} =
Metadata.add_book_to_related_editions_registry("Book2", "1234567891", "An description2", nil)
end
end
describe "books alternatives names" do
test "new book has no alternatives names" do
{:ok, book} = Metadata.create_book("Book", "1234567890", "An description")
assert {:ok, alternatives_names} = Metadata.get_book_alternative_editions(book)
assert alternatives_names = []
end
test "book has related book so they has one alternative name" do
{:ok, related_book} = Metadata.create_book("Book", "1234567890", "An description")
{:ok, book} =
Metadata.add_book_to_related_editions_registry("Book2", "1234567891", "An description2", related_book.id)
assert {:ok, alternatives_names} = Metadata.get_book_alternative_editions(book)
assert alternatives_names = [related_book]
end
end
end
Loading…
Cancel
Save