You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.1 KiB

defmodule DecentralisedBookIndex.Metadata.Book do
use Ash.Resource,
otp_app: :decentralised_book_index,
domain: DecentralisedBookIndex.Metadata,
data_layer: AshPostgres.DataLayer
require Ash.Query
alias DecentralisedBookIndex.Metadata
postgres do
table "books"
repo DecentralisedBookIndex.Repo
end
actions do
defaults [:read, :update, :destroy]
create :create do
primary? true
accept [:title, :description, :format, :language, :page_count, :published, :publisher_id, :book_editions_registry_id]
argument :bids, {:array, :map}
argument :author_roles, {:array, :map}
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
change manage_relationship(:bids, type: :direct_control, order_is_key: :order)
change manage_relationship(:author_roles, type: :direct_control, order_is_key: :order)
end
create :add_book_to_related_editions_registry do
accept [:title, :description, :format, :language, :page_count, :published, :publisher_id]
argument :related_book_id, :uuid do
allow_nil? false
end
argument :bids, {:array, :map}
argument :author_roles, {:array, :map}
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
change manage_relationship(:bids, type: :direct_control, order_is_key: :order)
change manage_relationship(:author_roles, type: :direct_control, order_is_key: :order)
end
read :by_id do
argument :id, :uuid, allow_nil?: false
get? true
filter expr(id == ^arg(:id))
end
read :by_bid do
argument :type, :string, allow_nil?: false
argument :bid, :string, allow_nil?: false
get? true
filter expr(exists(bids, type == ^arg(:type) and bid == ^arg(:bid)))
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
read :get_author_books do
argument :author, :struct, allow_nil?: false
prepare fn query, context ->
author = query.arguments.author
{:ok, author_ids} = Metadata.get_author_ids(author)
Metadata.Book
|> Ash.Query.filter(expr(exists(author_roles, author_id in ^author_ids)))
end
end
end
attributes do
uuid_primary_key :id
attribute :title, :string do
allow_nil? false
public? true
end
attribute :description, :string do
allow_nil? false
public? true
end
attribute :published, :date do
allow_nil? false
public? true
end
attribute :language, :string do
allow_nil? false
public? true
end
attribute :format, :string do
allow_nil? false
public? true
end
attribute :page_count, :integer do
allow_nil? false
public? true
end
timestamps()
end
relationships do
belongs_to :book_editions_registry, Metadata.BookEditionsRegistry
belongs_to :publisher, Metadata.Publisher
has_many :author_roles, Metadata.AuthorRole do
sort order: :asc
public? true
end
has_many :bids, Metadata.BookId do
sort order: :asc
public? true
end
end
end