anibal

anibal

Having trouble understanding the Centralized Code Interface code example in the Ash Docs

I have been studying the the beta of the Ash Book and going through the docs, and I am having some difficulties grasping this code example from the docs

defmodule MyApp.Tweets do
  use Ash.Domain

  resources do
    resource MyApp.Tweets.Tweet do
      # define a function called `tweet` that uses
      # the `:create` action on MyApp.Tweets.Tweet
      define :tweet, action: :create, args: [:text]
    end

    resource MyApp.Tweets.Comment do
      # define a function called `comment` that uses
      # the `:create` action on MyApp.Tweets.Comment
      define :comment, action: :create, args: [:tweet_id, :text]
    end
  end
end

Which is supposed to allow:

tweet = MyApp.Tweets.tweet!("My first tweet!", actor: user1)
comment = MyApp.Tweets.comment!(tweet.id, "What a cool tweet!", actor: user2)

In my mind the define is operating nested inside a Resource definition and the tweet! and comment! functions should be defined at the Resource level and not at the Domain level.

Again in my mind the define “should” work something like:

define :tweet, module: :MyApp.Tweets.Tweet, action: :create, args: [:text]

Not sure if this is related to me trying to learn Elixir at the same time that I am learning Ash, for sure that is not helping and I have a deep dive on macros and alikes pending.

Thanks in advance on your guidance!

Most Liked

ken-kost

ken-kost

Imagine if you had a 100 interfaces for a resource (extreme example), in your example you would have to repeate same module/resource for each. The way it is now, you just put them in the resource block; or define them in the resource.

But I think I understand what you mean: it’s more intuitive to define it as an option. But in the case of defining an interface in a resource, what then? You wouldn’t mention the module? It would be less consistent.

sodapopcan

sodapopcan

Ya it’s funny—I think it does have to do with being new to Elixir because I see what OP means now that they’ve pointed it out but this never once occurred to me before!

@anibal maybe thinking of it as with_resource do would help but as mentioned, it’s really just about getting a clean way to define things. Macro-heavy DSLs can take some getting used to. It’s probably easier to not think of resources and resource as function calls but as a simplified language for creating data structures that are then fed into “real” functions. Incidentally, this is exactly what is happening behind the scenes!

For example, would the following be as surprising? (Note, this is a completely invented simplified example):

defmodule MyApp.Tweets do
  @behaviour Ash.Domain

  @impl true
  def domain do
    %{
      resources: [
        %{
          module: MyApp.Tweets.Tweet,
          define: [
            :tweet, action: :create, args: [:text]
          ]
        },
        %{
          module: MyApp.Tweets.Comment,
          define: [
            :comment, action: :create, args: [:tweet_id, :text]
          ]
        }
      ]
    }
  end
end

Ash could have been done in a manner like that, but the DSL is much nicer.

zachdaniel

zachdaniel

Creator of Ash

By defining the interface on the domain, you get something more akin to a “service”. i.e

MyApp.Accounts.register_user!(...)

vs

MyApp.Accounts.User.register_user!()

Defining them on the domain for the most part decouples the caller from the resource in charge of registering said user.

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call t...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New

Other popular topics Top

malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement