Update a record loaded from a different table name with ecto changeset

I loaded my data from a query with a recursive cte as demonstrated in the ecto documentation, and I only need the categories, so my code looks like this:

{"category_tree", Category}
|> recursive_ctes(true)
|> with_cte("category_tree", as: ^category_tree_query)
|> Repo.all()

What I can get from this query is:

 %Category{
    __meta__: #Ecto.Schema.Metadata<:loaded, "category_tree">,
   name: "root"
   ...
}

Note that the source in the schema is name of the recursive CTE category_tree instead of categories here.

The problem is when I change the record with changeset api and pass the changeset to the repo, it will try to update the category_tree table.

My question is that is there any way to force ecto to apply the changeset against categories table without reload the struct from database?

I can bypass this problem by add another layer of select when loading the record:

category_tree_query = 
  {"category_tree", Category}
  |> recursive_ctes(true)
  |> with_cte("category_tree", as: ^category_tree_query)
  |> select([cat], cat.id)

from(c in Category, where: c.id in subquery(category_tree_query))
|> Repo.all()

However I’m still curious if there are other solutions.

1 Like