0
votes

I'm trying to create a many to many relationship using the current user assignment in the connection. The problem is I don't have access to conn in the model. I've tried passing it with the changeset, but that didn't seem like the right way to do it.

What's the best way to handle this? I imagine I can import conn into models. Is there any reason I wouldn't want to do that?

Here is what my changeset looks like right now

def changeset(model, user, params \\ :invalid) do
    model
    |> cast(params, @required_fields)
    |> put_assoc(:users, [user])
    |> validate_required([:name])
    |> unique_constraint(:name)
end

UPDATE

Ended up going with Steve's suggestion. Added a virtual field for the user id to the schema and this function to the changeset pipeline

  def changeset(model, params \\ :invalid) do
    model
    |> cast(params, @required_fields)
    |> associate_current_user(params)
    |> validate_required([:name])
    |> unique_constraint(:name)
  end

  def associate_current_user(model, params) do
    case params do
      %{"user_id" => id} ->
        user = Repo.get!(User, id)

        model
        |> put_assoc(:users, [user])
      _ ->
        model
    end
  end
2

2 Answers

1
votes

Why don't you just add the current user_id into the params and handle it that way. If the new/update is coming from a web form, its easy to get current_user in the template and add a hidden input.

3
votes

I wouldn't do that. It might be tempting at first, but later it will be confusing for you or someone else, who will maintain this code.

Model is separate layer of your app, so using conn in that area would couple it with controller quite closely. Though, models are just a Elixir modules so in perfect world you could use them without Phoenix and request / response cycle.

Also consider unit testing for that function - can you make sure that conn always looks like what you need and require?

Don't mix concerns. For orchestrating the conn flow you have controllers and from Phoenix 1.3 to manage the schemas, you have bounded contexts.