Comments (12)
Is the user an Ecto model, such that this would be better treated as a has_many
? If not, could you just use a function instead?
from ex_machina.
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 create
would work, but would probably not be any better than what I'm doing now. I think it would be nice to be able to avoid that repetition if possible. I also think it would work well if user was an Ecto model
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
from ex_machina.
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
from ex_machina.
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
from ex_machina.
One minor issue with this solution is that you can't do user_event.()
, should you like to, because
anonymous functions can't have variable numbers of arguments.
Then again, user_event.([])
works fine.
from ex_machina.
For the fun of it, here's a slightly evil version abusing Records: https://gist.github.com/henrik/bff879a97f7df44a8830
from ex_machina.
@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 create
that gets merged into the passed in atrributes, but honestly I'm not sure I like it much :S
attrs = [user_id: 123]
create(:event, attrs, name: "cancelled")
If you have any other ideas feel free to post here them here :)
from ex_machina.
Something like this might work too, but you'd have to put the .
before the parens which is less than ideal :S
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
from ex_machina.
On 13 Oct 2015, at 18:41, Paul Smith [email protected] wrote:
Another option might be to just allow another parameter in create that gets merged into the passed in atrributes, but honestly I'm not sure I like it much :Sattrs = [user_id: 123]
create(:event, attrs, name: "cancelled")
Oh yeah, I considered that also but forgot to mention it. I think it's got a few things going for it. It's super simple, for one. It's also a bit reminiscent of FactoryGirl traits.
from ex_machina.
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.
from ex_machina.
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
from ex_machina.
I'm going to close this and revisit it later. Right now it's not a priority right now.
from ex_machina.
Related Issues (20)
- def build/2 defines defaults multiple times HOT 2
- Use of `build( ... )` with Ecto 3.4+ leads to many association preload warnings HOT 7
- Compiler warning when using an a project using Elixir 1.11 HOT 3
- Insert with assocs fails constraint HOT 1
- Proposal: Introduce build_lazy/2 HOT 3
- Test-only implementation fails HOT 4
- Cast polymorphic embeds HOT 7
- Inserted data breaks manual test HOT 3
- Allow sequence in attributes passed to `insert_list` HOT 5
- Hundreds of depreciation compiler warnings when running tests HOT 4
- insert/2 doesn't work with compound primary keys HOT 3
- Allow sequences indices to be persisted between runs HOT 2
- sequence starting with 0
- Is this project maintained? HOT 17
- Sequence reset doesn't respect the `start_at` option
- sequence(:example_id, & &1) put chars instead of integer HOT 3
- Stringify `Ecto.Enum` values when using `string_params`/`string_params_with_assocs`
- Option to have `insert_list` leverage Ecto's `insert_all`
- an intermittent error on async false tests HOT 1
- nvim diagnostics error HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ex_machina.