Смешивание областей и ассоциаций в Phoenix/Ecto
В Rails, если у меня есть следующая настройка:
class Post < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :post
def self.approved
where(approved: true)
end
end
Тогда я могу сделать что-то вроде этого:
post = Post.find(100)
comments = post.comments.approved
чтобы быстро получить все одобренные комментарии для данного Post
.
Как я могу сделать что-то подобное в Ecto?
defmodule MyApp.Post do
use Ecto.Model
schema "posts" do
#columns omitted
has_many :comments, MyApp.Comment
end
end
defmodule MyApp.Comment do
use Ecto.Model
schema "comments" do
#columns omitted
belongs_to :post, MyApp.Post
end
end
У меня есть Post
с comments
pre-loaded:
post = MyApp.Post
|> MyApp.Repo.get(100)
|> MyApp.Repo.preload(:comments)
Я даже не уверен, с чего начать с области approved
в MyApp.Comment
.
Ответы
Ответ 1
Предварительные загрузки могут принимать запросы. Таким образом, вы можете фильтровать связанные комментарии, подобные этому.
post =
MyApp.Post
|> Ecto.Query.preload(comments: ^MyApp.Comment.approved(MyApp.Comment))
|> MyApp.Repo.get(100)
И в вашей модели Comment
def approved(query) do
from c in query,
where: c.approved == true
end
Ответ 2
Я не думаю, что это возможно с текущей версией Ecto. Предварительная загрузка не позволяет фильтровать. Альтернатива заключается в том, чтобы получить комментарии с запросом:
(from comment in MyApp.Comment,
where: comment.post_id == ^post_id
and comment.approved == true,
select: comment) |> Repo.all