Giter Site home page Giter Site logo

Comments (12)

jsteiner avatar jsteiner commented on May 6, 2024

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.

paulcsmith avatar paulcsmith commented on May 6, 2024

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.

henrik avatar henrik commented on May 6, 2024

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.

henrik avatar henrik commented on May 6, 2024

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.

henrik avatar henrik commented on May 6, 2024

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.

henrik avatar henrik commented on May 6, 2024

For the fun of it, here's a slightly evil version abusing Records: https://gist.github.com/henrik/bff879a97f7df44a8830

from ex_machina.

paulcsmith avatar paulcsmith commented on May 6, 2024

@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.

paulcsmith avatar paulcsmith commented on May 6, 2024

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.

henrik avatar henrik commented on May 6, 2024

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 :S

attrs = [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.

henrik avatar henrik commented on May 6, 2024

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.

paulcsmith avatar paulcsmith commented on May 6, 2024

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.

paulcsmith avatar paulcsmith commented on May 6, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.