在Phoenix/Ecto中混合范围和关联

Eri*_*kas 26 elixir ecto phoenix-framework

在Rails中,如果我有以下设置:

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post

  def self.approved
    where(approved: true)
  end
end
Run Code Online (Sandbox Code Playgroud)

然后我可以做这样的事情:

post = Post.find(100)
comments = post.comments.approved
Run Code Online (Sandbox Code Playgroud)

快速获得给定的所有批准的评论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
Run Code Online (Sandbox Code Playgroud)

postcomments预装的:

post = MyApp.Post
       |> MyApp.Repo.get(100)
       |> MyApp.Repo.preload(:comments)
Run Code Online (Sandbox Code Playgroud)

我甚至不确定从哪个approved范围开始MyApp.Comment.

Dmi*_*kyy 10

允许预加载接收查询.所以你可以像这样过滤相关的评论.

post = 
  MyApp.Post
  |> Ecto.Query.preload(comments: ^MyApp.Comment.approved(MyApp.Comment))
  |> MyApp.Repo.get(100)
Run Code Online (Sandbox Code Playgroud)

在你的Comment模型中

def approved(query) do
  from c in query,
  where: c.approved == true
end
Run Code Online (Sandbox Code Playgroud)


ash*_*ash 3

我认为当前版本的 Ecto 不可能实现这一点。预加载不允许过滤。另一种方法是通过查询获取评论:

(from comment in MyApp.Comment, 
  where: comment.post_id == ^post_id 
    and comment.approved == true,
select: comment) |> Repo.all
Run Code Online (Sandbox Code Playgroud)