https://hexdocs.pm/ash/get-started.html 를 따라가며 Ash 프레임워크를 살펴 본다. 이전 글에 이어서 Ticket 리소스를 개선한다.
Helpdesk.Support.Ticket |> Ash.Changeset.for_create(:create) |> Ash.create!() 를 통해 Ticket 데이터를 만들 수 는 있었지만 subject 를 입력할 수도 상태를 지정할 수 도 없었다. 보통 create 함수에 처음 세팅할 값을 전달하거나 create 함수 내부에서 기본 값을 설정하는 등 일정 로직이 필요하다.
먼저 Ticket 리소스의 attribute 들에 몇가지 속성을 추가하자.
# lib/helpdesk/support/ticket.ex
attributes do
...
attribute :subject, :string do
allow_nil? false
public? true
end
attribute :status, :atom do
constraints [one_of: [:open, :closed]]
default :open
allow_nil? false
end
end
subject attribute에는 nil 을 허용하지 않는 속성이 추가되었고 public 속성이 이 true 가 되었다. 여기서 public/private 은 REST/GraphQL 등 외부 API로 노출되었을때에 대한 가시성을 의미한다. public 이면 나중에 API 로 접근할 경우 필드로 나타날 것이다. public? 으로 명시하지 않으면 기본적으로 모두 private 이다. 내부적 접근 (예를들어 subject = ticket.subject 같은) 과는 상관이 없다.
status attribute 가 추가되었고 자료형은 atom, 값에 대한 제약조건이 :open, :closed 중 한개로 제약 조건이 붙었다. 기본 값은 :open 이다.
attribute 를 보완했으니 create 액션도 보완할 차례다.
# lib/helpdesk/support/ticket.ex
actions do
...
create :open do
accept [:subject]
end
end
create :create 에서 create :open 으로 변경되었다. create 액션의 이름이 :open 로 변경된 것이다. Ash.Changeset.for_create 호출 파라미터도 :open 으로 바뀌어야 한다. accept 은 값을 인자로 전달받을 attribute 를 지정한다. attribute 로 지정되어 있지 않은 이름을 atom 으로 작성하면 거절(컴파일 오류) 된다.
변경된 Ticket 리소스의 형태는 다음과 같다.
defmodule Helpdesk.Support.Ticket do
use Ash.Resource, domain: Helpdesk.Support
actions do
defaults [:read]
create :open do
accept [:subject]
end
end
attributes do
uuid_primary_key :id
attribute :subject, :string do
allow_nil? false
public? false
end
attribute :status, :atom do
constraints one_of: [:open, :closed]
default :open
allow_nil? false
end
end
end
iex 를 재실행하거나 recompile() 해서 코드를 업데이트 하고 다음과 같이 값을 전달하여 Ticket을 만든다.
iex> recompile()
iex> Helpdesk.Support.Ticket
|> Ash.Changeset.for_create(:open, %{subject: "My mouse won't click!"})
|> Ash.create!()
%Helpdesk.Support.Ticket{
id: "d29d5348-ff98-4cc2-adbd-bffe29cef64f",
subject: "My mouse won't click!",
status: :open,
__meta__: #Ecto.Schema.Metadata<:built, "">
}
입력 값이 잘못되거나 액션 이름이 잘못되었다면 에러가 발생한다.
iex> ticket = Helpdesk.Support.Ticket|> Ash.Changeset.for_create(:open, %{subject1: "My mouse won't click!"})|> Ash.create!()
** (Ash.Error.Invalid)
Bread Crumbs:
> Error returned from: Helpdesk.Support.Ticket.open
Invalid Error
* No such input `subject1` for action Helpdesk.Support.Ticket.open
No such attribute on Helpdesk.Support.Ticket, or argument on Helpdesk.Support.Ticket.open
Did you mean:
* subject
Valid Inputs:
* subject
iex> ticket = Helpdesk.Support.Ticket|> Ash.Changeset.for_create(:open)|> Ash.create!()
** (Ash.Error.Invalid)
Bread Crumbs:
> Error returned from: Helpdesk.Support.Ticket.open
Invalid Error
* attribute subject is required
다음 글에서는 레코드의 변경과 검증에 대해 알아 보자.