New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ExMachina.with_attrs/1 #33
Comments
Is the user an Ecto model, such that this would be better treated as a |
No the user is not an Ecto model. It is just an integer in this case. It is working with an external data source. Calling a function on each user = create(:user)
ExMachina.with(user: user) do
create(:event, name: "whatever")
create(:event, name: "foo")
end Maybe you have another idea though? I'd love to use a regular function and not a macro if possible |
Sketched out one idea of how this could be done without macros, just for fun. I guess this isn't currying in a strict sense, so it might not be a good idea to keep that name. defmodule ExMachina do
def example do
user_event = curry(:create, :event, user: 123)
# Instead of…
create(:event, name: "started", user: 123)
create(:event, name: "finished", user: 123)
# Try…
user_event.(name: "started")
user_event.(name: "finished")
end
def curry(action, model, defaults) do
fn (attrs) ->
full_attrs = Keyword.merge(defaults, attrs)
apply(__MODULE__, action, [model, full_attrs])
end
end
def create(model, attrs) do
IO.puts "create #{model} with #{inspect attrs}"
end
end
ExMachina.example |
If it's a common use case for a single attribute to vary, one could even do this: def example do
user_event = curry(:create, :event, :name, user: 123)
user_event.("started")
user_event.("finished")
end
def curry(action, model, attribute_name, defaults) do
fn (attribute_value) ->
full_attrs = Keyword.merge(defaults, [{attribute_name, attribute_value}])
apply(__MODULE__, action, [model, full_attrs])
end
end |
One minor issue with this solution is that you can't do Then again, |
For the fun of it, here's a slightly evil version abusing Records: https://gist.github.com/henrik/bff879a97f7df44a8830 |
@henrik Those are some interesting ideas. I'm not sure if/which option we will go with but this definitely made me think :) I would like to avoid a macro if possible, but also have a nice clean API. Another option might be to just allow another parameter in attrs = [user_id: 123]
create(:event, attrs, name: "cancelled") If you have any other ideas feel free to post here them here :) |
Something like this might work too, but you'd have to put the w = ExMachina.with(MyApp.Factory, user_id: 123)
w.create.(:event, name: "cancelled) defmodule ExMachina.with do
def with(module, default_attrs) do
default_attrs = Enum.into(%{})
%{
create: fn(factroy, attrs) ->
ExMachina.create(module, Map.merge(default_attrs, attrs))
end),
build: fn(factory, attrs) -> ExMachina.build...
}
end
end |
|
Another simple one: with_user = [user: 123]
ExMachina.create(:event, with_user ++ [name: "started"]) Don't like how you need to add in the square brackets, though. And it creates duplicate keys if they're in both lists, which I'm not sure how ExMachina handles. |
I believe we could do something very similar to what's done with Ecto migrations. See Henrik's example here: https://gist.github.com/henrik/25516815e6680e1c7a82 I believe this would allow us to have the syntax: MyApp.Factory.with_attrs(user_id: 1) do
create(:event)
end The problem with this is that I don't think you could pipe other functions because I don't think they would be available inside this scope. I'd have to try it out |
I'm going to close this and revisit it later. Right now it's not a priority right now. |
Recently I had to create a lot of events that all had the same
user_id
I think it would be nice to have a function that allows you do to something like this
I'm not exactly sure how this would work, or if this is the syntax/naming we want, but I think we could come up with something
The text was updated successfully, but these errors were encountered: