Using code_interface args

When I use
code_interface do
define_for Office.ToDoList
define :create, args: [:subject]
end
code_interface do
define_for Office.ToDoList
define :create, args: [:subject]
end
I have access to Office.ToDoList.Task.create!("test") but not to Office.ToDoList.Task.create!(%{subject: "test2"}). For the later one to work I have to use define :create but then the first version doesn't work. Is there a way to have access to both versions or would that be a misuse of the code_interface concept?
4 Replies
ZachDaniel
ZachDaniel•2y ago
There is potentially a way for us to make both work, but its generally unreliable What you can do is put this at the bottom of your resource. (or maybe at the top)
def create(attrs) when is_map(attrs) do
create(attrs[:subject], attrs)
end

def create(attrs, opts) when is_map(attrs) do
create(attrs[:subject], attrs, opts)
end
def create(attrs) when is_map(attrs) do
create(attrs[:subject], attrs)
end

def create(attrs, opts) when is_map(attrs) do
create(attrs[:subject], attrs, opts)
end
Stefan Wintermeyer
Stefan WintermeyerOP•2y ago
For me it is more a question of understanding the "Ash way". I can work with both. I just want to get a feeling when to use args: and when not to. I can't use them on all resources so I am thinking "Is it a good idea to have two different ways of using this in the same project?"
ZachDaniel
ZachDaniel•2y ago
I wouldn't 🙂 Although I do see what you're getting at by having one that accepts attributes as a map and one that doesn't But if you have attribtues as a map, its usually from input and from user input, you will typically want to do things like use an AshPhoenix.Form, or Ash.Changeset.for_create(... If you had this
define :create, args: [:subject]
define :create, args: [:subject]
you can call it four ways
.create(subject)
.create(subject, []) # opts is a keyword
.create(subject, %{}) # attributes is a map
# we can tell the two above apart because of map vs keyword
.create(subject, %{}, [])
.create(subject)
.create(subject, []) # opts is a keyword
.create(subject, %{}) # attributes is a map
# we can tell the two above apart because of map vs keyword
.create(subject, %{}, [])
So you can include additional attributes free-form
Stefan Wintermeyer
Stefan WintermeyerOP•2y ago
Thanks!

Did you find this page helpful?