2015-06-01 10 views
23

In Rails, wenn ich die folgende Konfiguration haben:Mischen Scopes und Verbände in Phoenix/Ecto

class Post < ActiveRecord::Base 
    has_many :comments 
end 

class Comment < ActiveRecord::Base 
    belongs_to :post 

    def self.approved 
    where(approved: true) 
    end 
end 

Dann kann ich etwas tun:

post = Post.find(100) 
comments = post.comments.approved 

schnell die genehmigten alle Kommentare zu erhalten, für das gegebene Post.

Wie kann ich etwas ähnliches in Ecto tun?

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 

Ich habe die post mit comments vorbelastet:

post = MyApp.Post 
     |> MyApp.Repo.get(100) 
     |> MyApp.Repo.preload(:comments) 

Ich bin nicht einmal sicher, wo mit dem approved Umfang in MyApp.Comment zu starten.

+3

Dieser Blog-Eintrag Sie in die richtige Richtung zeigen kann: http://blog.drewolson.org/composable-queries-ecto/ – Gazler

Antwort

3

Ich glaube nicht, dass es mit der aktuellen Version von Ecto möglich ist. Preload erlaubt keine Filterung. Alternative ist es, die Kommentare mit einer Abfrage zu erhalten:

(from comment in MyApp.Comment, 
    where: comment.post_id == ^post_id 
    and comment.approved == true, 
select: comment) |> Repo.all 
9

Preloads dürfen Abfragen erhalten. So können Sie verknüpfte Kommentare wie folgt filtern.

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

Und in Ihrem Comment Modell

def approved(query) do 
    from c in query, 
    where: c.approved == true 
end