luzny
luzny

Reputation: 2400

How to use custom preload function after insert?

How to use custom model function to preload selected data after Repo.insert? I won't duplicate code from model in controller.

In Post Model:

def preload_all(query) do
  tags = from(t in Tag, select: %{id: t.id, value: t.id})
  from b in query, preload: [:user, tags: ^tags]
end

In Controller:

case Repo.insert(changeset) do
  {:ok, post} ->
    # post = post |> Post.preload_all
    post = Repo.preload(post, [:user, :tags])
end

Upvotes: 2

Views: 4420

Answers (1)

Dogbert
Dogbert

Reputation: 222198

There are two ways I can think of:

  1. Pass in a query which fetches post with id = post.id:

    case Repo.insert(changeset) do
      {:ok, post} ->
        post = Repo.one(Post.preload_all(from p in Post, where: p.id == ^post.id))
    end
    

    Note that this will execute one more query than required.

  2. Extract the preload parameters to a different function and use it from both the controller and the model:

    # Post Model
    def preload_args do
      tags = from(t in Tag, select: %{id: t.id, value: t.id})
      [:user, tags: tags]
    end
    
    def preload_all(query) do
      from b in query, preload: ^preload_args
    end
    
    # Controller
    case Repo.insert(changeset) do
      {:ok, post} ->
        post = Repo.preload(post, Post.preload_args)
    end
    

(All code untested; please point out syntax or other errors if you spot any.)

Upvotes: 5

Related Questions