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.

329 lines
7.9 KiB

defmodule DecentralisedBookIndex.Metadata.Book do
use Ash.Resource,
otp_app: :decentralised_book_index,
domain: DecentralisedBookIndex.Metadata,
data_layer: AshPostgres.DataLayer,
extensions: [AshJsonApi.Resource]
require Ash.Query
alias DecentralisedBookIndex.Metadata
json_api do
type "book"
end
postgres do
table "books"
repo DecentralisedBookIndex.Repo
end
actions do
defaults [:read, :destroy]
create :create do
primary? true
accept [
:title,
:description,
:format,
:language,
:page_count,
:published,
:publisher_id,
:cover_image_url,
: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 :sync_create do
accept [
:id,
:title,
:description,
:format,
:language,
:page_count,
:published,
:publisher_id,
:cover_image_url,
:book_editions_registry_id,
:inserted_at,
:updated_at,
:dbi_server_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,
:cover_image_url
]
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
read :search do
argument :query, :ci_string do
constraints allow_empty?: true
default ""
end
filter expr(contains(title, ^arg(:query)))
pagination offset?: true, default_limit: 10
end
update :update do
primary? true
require_atomic? false
accept [
:title,
:description,
:format,
:language,
:page_count,
:published,
:publisher_id,
:cover_image_url,
: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
update :sync do
require_atomic? false
accept [
:id,
:title,
:description,
:format,
:language,
:page_count,
:published,
:publisher_id,
:cover_image_url,
:book_editions_registry_id,
:inserted_at,
:updated_at,
:dbi_server_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
update :assign_cover_image do
accept [:cover_image_url]
end
end
attributes do
uuid_primary_key :id, writable?: true
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
attribute :cover_image_url, :string do
allow_nil? true
public? true
end
timestamps() do
writable? true
public? true
end
end
validations do
validate numericality(:page_count, greater_than: 0)
end
relationships do
belongs_to :dbi_server, Metadata.DBIServer
belongs_to :book_editions_registry, Metadata.BookEditionsRegistry
belongs_to :publisher, Metadata.Publisher do
public? true
end
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