Mediumでたまたま Repository Pattern を見たこともあって、 Ecto.Repo を見てみました。こういうまとまっているフレームワーク見ると、手軽なデザインパターンの理解や頭の整理にもなりますよね。
Ecto.Query付近は随分前にざっと見ているので、今回は別。
[Elixir]EctoのQueryを少し読み解く ~ コードに前提条件が書かれるので読み解きやすいですね ~
Ecto 2.0から、 Ecto.Repo.first とかもdeprecatedになったので、その対応をついでにメモ。
以下の User は、 Ecto.scheme によって定義されたmodelです。それに対して、1件のemailに合致するデータを引っ張ってくるという処理です。
User |> Repo.first(email: email)
この Repo.first がdeprecatedなので、それをQueryを使って書き直すと以下のように書くことができます。
User |> Ecto.Query.first(email: email) |> Repo.one
この時、 Ecto.Query.first の結果は以下のようになります。
#Ecto.Query<from u in MyApp.User, order_by: [asc: u.id], limit: 1>
ここは、実際にSQLを出す前のQueryを構築するところです。この Repo.one が実施されると、SQLが発行されてその結果がmodelの結果として得られます。以下は Repo.one まで行われた結果です。
%MyApp.User{
__meta__: #Ecto.Schema.Metadata<:loaded>,
email: nil,
encrypted_password: nil,
id: 706,
inserted_at: #Ecto.DateTime<2016-04-24 11:54:06>,
is_deleted: false,
name: nil,
password: nil,
permission: 0,
updated_at: #Ecto.DateTime<2016-04-24 11:54:06>
}
Ecto.Query.first ではリクエストしたいSQLの構築、 Repo.one で実行と、クエリ構築とその実行が分離されていますね。
変更したdiffを合わせて置いておきます。
https://github.com/KazuCocoa/web_qa_vote/commit/4a0242455fb3b9c15d5c68d5e8e78336a2474b54