Reputation: 11153
Phoenix Framework 1.0.2
I have a user_post_path()
because I am making Users
has_many
Posts
.
in my Posts controller I do:
def show(conn, %{"id" => id, "user_id" => user_id}) do
post = Post |> Repo.get!(id)
user = User |> Repo.get!(user_id)
render(conn, :index, post: post, user: user)
end
in my post/show.html
I have:
<%= link "Edit", to: user_post_path(@conn, :edit, @user, @post) %>
First question, is it inefficient to write 2 queries? ie.
Repo.get!(id)
and Repo.get!(user_id)
Or is it more efficient to write something like this:
user_with_post = User |> Repo.get!(user_id) |> Repo.preload [:posts] |> #now do something to get posts.id = 5 for example
I assume it is more efficient to write one query, (please correct me if I'm wrong!), which leads me to my second question.
Once I preload posts, I can't simply Repo.get(post_id)
because I get "not a queryable" error. What is the proper way to filter the posts of a user so that I only get the users details with the specific post id/ids I want?
Upvotes: 3
Views: 765
Reputation: 84140
Both methods (calling Repo.get!
twice and using Repo.preload
) will make two queries. You can verify this by looking in your phoenix console when calling the show action.
However if there is a has many association but you only want one of the users posts, I would write:
def show(conn, %{"id" => id, "user_id" => user_id}) do
user = User |> Repo.get!(user_id)
post = assoc(user, :posts) |> Repo.get!(post_id)
render(conn, :index, post: post, user: user)
end
Using assoc/2 you can ensure that the post belongs to the user - which is what I believe you are trying to do.
Upvotes: 3