1
votes

I'm trying to paginate data that has preloaded associations.

In my controller this works:

  def index(conn, _params) do
    products = Product
        |> Repo.all
        |> Repo.preload(:category)

    render(conn, "index.html", products: products)
  end

And this also works:

  def index(conn, params) do
    {products, kerosene} = Product
    |> Repo.paginate(params)

    render(conn, "index.html", products: products, kerosene: kerosene)
  end

But combining them produces argument error on line |> Repo.paginate(params)

  def index(conn, params) do
    {products, kerosene} = Product
    |> Repo.all
    |> Repo.preload(:category)
    |> Repo.paginate(params)

    render(conn, "index.html", products: products, kerosene: kerosene)
  end

If I drop line |> Repo.all it produces:

no function clause matching in Ecto.Repo.Preloader.preload/4" on line |> Repo.preload(:category)
1

1 Answers

1
votes

Assuming you're using Kerosene, Repo.paginate expects a query as argument while Repo.all |> Repo.paginate returns a list of structs. You can use either Ecto.Query.preload or create a query using from with a preload attribute to generate a query which automatically preloads when it's run.

{products, kerosene} =
  Product
  |> Ecto.Query.preload(:category)
  |> Repo.paginate(params)

# or

{products, kerosene} =
  from(p in Product, preload: :category)
  |> Repo.paginate(params)