
翻訳者から:「 エリクサーとフェニックスは、最新のウェブ開発がどこに進んでいるかの良い例です。 すでにこれらのツールは、Webアプリケーションのリアルタイムテクノロジーへの質の高いアクセスを提供します。 対話性が向上したサイト、マルチユーザーブラウザーゲーム、マイクロサービスは、これらの技術がうまく機能する分野です。 以下は、Phoenixフレームワークでの開発の詳細な側面を説明する一連の11の記事の翻訳です。ブログエンジンのような些細なことのように思えます。 しかし、急いでつまずかないでください。特に記事がエリクサーに注意を払うか、彼のフォロワーになるように促す場合、それは本当に面白いでしょう。
このパートでは、Phoenixチャンネルを使用してアニメーション化できるように、コメントの基盤を準備します。
現時点では、アプリケーションは以下に基づいています。
- エリクサー :v1.3.1
- フェニックス :v1.2.0
- Ecto:v2.0.2
どこで止めたの
エンジンは小さなMarkdownエディターを使用して投稿を装飾できるようになったため、私たちのクラフトは本格的なプロジェクトのようになりました! ただし、作成した投稿に関するフィードバックを受け取る方法はまだありません。 幸いなことに、この機能の追加は非常に簡単です。 すべての作業は、すでに行ったことに基づいて行われます。
簡単なものから始めましょう。 登録の要件の代わりに、承認待ちの状態で新しいコメントを作成します。 コメントは、確認後すぐに投稿ページに表示されるか、「未確認を表示」をクリックして表示されます。
コメントモデルを追加
コメント用のモデルを追加することから始めましょう。 コメントは次のとおりです。
- 著者(文字列型)
- メッセージ(テキストタイプ)
- 承認済みコメントのサイン(ブール値、デフォルトではfalse)
- コメントが参照する投稿(投稿のあるテーブルへのリンク)
テンプレートやその他のアメニティの完全なセットは必要ないため、
mix phoenix.gen.model
を使用します。
mix phoenix.gen.model Comment comments author:string body:text approved:boolean post_id:references:posts
次に、移行します。
mix ecto.migrate
コメントを投稿にリンクする
web/models/comment.ex
は、コメントがすでに投稿に関連付けられていることがわかりますが、反対方向のコミュニケーションは十分ではありません。
したがって、
web/models/post.ex
ファイルの「posts」スキーマの定義に次のコードを追加します。
has_many :comments, Pxblog.Comment
mix test
コマンドを実行した後、すべてが緑色になっているはずです! では、投稿とコメントの関係を確認しましょう。
これを行うには、ファイル
test/support/factory.ex
を開き、コメントファクトリを追加します。 ファイルの先頭に次の行を書き、その後に他のエイリアスを続けます。
alias Pxblog.Comment
そして、このコードを一番下に:
def comment_factory do %Comment{ author: "Test User", body: "This is a sample comment", approved: false, post: build(:post) } end
したがって、ファクトリが有用になるように、いくつかのテストを作成する必要があります。 ファイル
test/models/comment_test.exs
を開き、次のコードを追加します。
import Pxblog.Factory # ... test "creates a comment associated with a post" do comment = insert(:comment) assert comment.post_id end
テストを再度実行します。 彼らは緑のままでなければなりません!
コメントのルートを追加する
基本的なコメントルートを作成することから始めましょう。
web/router.ex
。
resources "/posts", PostController, only: [] do resources "/comments", CommentController, only: [:create, :delete, :update] end
コメントは投稿のコンテキストでのみ意味があるため、コメントを内部に配置します。 同時に、すでに特定した他のルートでは、投稿はユーザーに投資されます! 投稿に不要なルートを作成したくないので、
only: []
パラメーター
only: []
使用します。 次に、コメント用のリソースを追加して、コメントを作成、削除、更新できるようにします。
:create
承認されていないユーザーによるコメントを追加します(未確認によって作成されます)。
:delete
-投稿の作成者および管理者がコメントを削除できるようにします。
:update
-公開表示のためにコメントを承認します。
コントローラーとビューを追加する
モデルが構成されたので、いくつかの方法でコントローラーを作成する必要があります。 コメントの表示はポストコントローラーを介して実装されますが、作成/更新/削除は独自のコントローラーで実装する必要があります。
web/controllers/comment_controller.ex
ファイルを作成することから始めましょう:
defmodule Pxblog.CommentController do use Pxblog.Web, :controller end
また、web / views / comment_view.exファイルに、Phoenixが望むようにビューを作成します。
defmodule Pxblog.CommentView do use Pxblog.Web, :view end
それでは、コントローラーに戻って、
create
、
update
および
delete
の3つのアクションの基本構造を追加しましょう。
def create(conn, _), do: conn def update(conn, _), do: conn def delete(conn, _), do: conn
次に、新しいディレクトリにコメントを追加するためのテンプレートを作成する必要があります。これは、投稿を表示するページに配置します。
$ mkdir web/templates/comment
ユーザーがコメントを残すことを許可します。
web/templates/comment/form.html.eex
作成することから始めましょう:
<%= form_for @changeset, @action, fn f -> %> <%= if @changeset.action do %> <div class="alert alert-danger"> <p>Oops, something went wrong! Please check the errors below.</p> </div> <% end %> <div class="form-group"> <%= label f, :author, class: "control-label" %> <%= text_input f, :author, class: "form-control" %> <%= error_tag f, :author %> </div> <div class="form-group"> <%= label f, :body, class: "control-label" %> <%= textarea f, :body, class: "form-control", id: "body-editor" %> <%= error_tag f, :body %> </div> <div class="form-group"> <%= submit "Submit", class: "btn btn-primary" %> </div> <% end %>
通常の形式、議論することは何もありません。
次に、
web/templates/post/show.html.eex
ファイルに移動して、このフォームへのリンクを追加します。 このテンプレートでは、2つの変数
@changeset
と
@action
を使用していることに注意してください。 これについては、
web/controllers/post_controller.ex
。 そして今、私たちはテンプレートを使い続けています。 投稿属性のリストの後に、次の行を追加します。
<%= render Pxblog.CommentView, "form.html", changeset: @comment_changeset, action: post_comment_path(@conn, :create, @post) %>
CommentView内の "form.html"を参照する必要があるため、
render
呼び出しの最初の引数として名前を渡します。
@comment_changeset
を渡す必要があり
@comment_changeset
(まだ決定していませんが、すぐに行います)。
@action
はコメントを送信する方法です。
これで、
web/controllers/post_controller.ex
に移動して機能させることが
web/controllers/post_controller.ex
。 コードに一致するようにshow関数を変更します。
def show(conn, %{"id" => id}) do post = Repo.get!(assoc(conn.assigns[:user], :posts), id) comment_changeset = post |> build_assoc(:comments) |> Pxblog.Comment.changeset() render(conn, "show.html", post: post, comment_changeset: comment_changeset) end
次に、CommentController(ファイル
web/controllers/comment_controller.ex
)に戻り、作成関数に内容を入力します。 関数の直前に、次のコードを追加します。
alias Pxblog.Comment alias Pxblog.Post plug :scrub_params, "comment" when action in [:create, :update]
scrub_params呼び出しに更新を含めることは、後で役立ちます。 create関数にジャンプして、次のコードをその中に配置します。
def create(conn, %{"comment" => comment_params, "post_id" => post_id}) do post = Repo.get!(Post, post_id) |> Repo.preload([:user, :comments]) changeset = post |> build_assoc(:comments) |> Comment.changeset(comment_params) case Repo.insert(changeset) do {:ok, _comment} -> conn |> put_flash(:info, "Comment created successfully!") |> redirect(to: user_post_path(conn, :show, post.user, post)) {:error, changeset} -> render(conn, Pxblog.PostView, "show.html", post: post, user: post.user, comment_changeset: changeset) end end
ここで、comment_paramsおよびpost_id投稿識別子を受け取るときに、必要に応じてコメントを作成します。 まず、リンクされた投稿をピックアップします(テンプレートが間もなくリンクを開始するため、ユーザーとコメントをプリロードすることを忘れないでください)。これに基づいて、新しいチェンジセットを作成します。 これを行うには、ポストから始めて、チェーンに沿って
build_assoc
関数に
build_assoc
、接続された回路を作成します。これはアトムを通じて定義します。 この場合、リンクされた
comment
が作成されます。 結果は、comment_paramsとともに、Comment.changeset関数に渡されます。 残りは1つの例外を除いて標準として機能します。
別のビューのレンダリングを使用しているため、エラー条件はもう少し複雑です。 まず、接続接続を渡し、次に関連するビュー(この場合は
Pxblog.PostView
)、レンダリング用のテンプレート、およびテンプレートで使用されるすべての変数
@post
、
@user
@post
、
@user
を
@comment_changeset
ます。 これでテストできます。エラーのあるコメントを送信すると、ページにそれらのリストが表示されます。 コメントの送信時にエラーがない場合は、ページの上部に青いフラッシュメッセージが表示されます。
コメント出力
次に、投稿ページにコメントを表示する必要があります。 これを行うには、さまざまな目的で任意の場所で使用できる一般的なコメントテンプレートを作成します。
web/templates/comment/comment.html.eex
を作成し、以下を入力します:
<div class="comment"> <div class="row"> <div class="col-xs-4"> <strong><%= @comment.author %></strong> </div> <div class="col-xs-4"> <em><%= @comment.inserted_at %></em> </div> <div class="col-xs-4 text-right"> <%= unless @comment.approved do %> <button class="btn btn-xs btn-primary approve">Approve</button> <% end %> <button class="btn btn-xs btn-danger delete">Delete</button> </div> </div> <div class="row"> <div class="col-xs-12"> <%= @comment.body %> </div> </div> </div>
ここでは説明なしですべてが明確です。 承認/削除ボタンはまだ接続されていません。 この問題は次の部分で解決します。 また、コメントをプリロードするようにコントローラーを変更し、ショー投稿テンプレートにコメントのリストを含める必要があります。 コントローラーを更新することから始めましょう。 投稿を受信する行の直後に、
web/controllers/post_controller.ex
から
show
関数に行を追加し
web/controllers/post_controller.ex
。
post = Repo.get!(assoc(conn.assigns[:user], :posts), id) |> Repo.preload(:comments)
このようにして、コメントが投稿の一部としてロードされるようにします。 最後に、
web/templates/post/show.html.eex
ファイルを開き、コメントを表示するテンプレートセクションを追加します。
<div class="comments"> <h2>Comments</h2> <%= for comment <- @post.comments do %> <%= render Pxblog.CommentView, "comment.html", comment: comment %> <% end %> </div>
コントローラーテストを追加する
いくつかの条件がテストでカバーされるまで停止できません。 コードはこれらのパスのいずれかを通過できるため、成功と失敗の場合にcreate関数をチェックする必要があります。
ファイル
test/controllers/comment_controller_test.exs
を作成して続行します。
defmodule Pxblog.CommentControllerTest do use Pxblog.ConnCase import Pxblog.Factory @valid_attrs %{author: "Some Person", body: "This is a sample comment"} @invalid_attrs %{} setup do user = insert(:user) post = insert(:post, user: user) {:ok, conn: build_conn(), user: user, post: post} end test "creates resource and redirects when data is valid", %{conn: conn, post: post} do conn = post conn, post_comment_path(conn, :create, post), comment: @valid_attrs assert redirected_to(conn) == user_post_path(conn, :show, post.user, post) assert Repo.get_by(assoc(post, :comments), @valid_attrs) end test "does not create resource and renders errors when data is invalid", %{conn: conn, post: post} do conn = post conn, post_comment_path(conn, :create, post), comment: @invalid_attrs assert html_response(conn, 200) =~ "Oops, something went wrong" end end
再びPxblog.Factoryファクトリを使用しましょう。 また、2つのモジュール変数
@valid_attrs
および
@invalid_attrs
を以前と同じ方法で設定します。 セットアップブロックを追加します。セットアップブロック内で、既定のユーザーと作業する投稿を構成します。
コメントを正常に追加するためのテストから始めましょう。 有効な属性を持つネストされたパスにPOSTリクエストを送信し、期待どおりにリダイレクトが機能し、コメントが投稿に追加されたことを確認します。
次に、同じことを行いますが、無効なデータを使用して、HTMLの形式で「エラーが発生しました」というメッセージを受け取ったことを確認します。 できた!

さらなるステップ
コメントのための素晴らしい基盤を用意しました。これは間違いなく開発を続けることができます。 たとえば、コメントを承認または削除することはできません。 次のいくつかのパートでは、Phoenixベースのライブコメントシステムに移行する前に、コメントの改善にもう少し取り組んでいきます。
シリーズの他の記事
Wunschからの結論
今年の2か月で、エリクサーのプロモーションの第一歩を踏み出すことができました。 まず、ロシア語コミュニティのWunsh.ruを設立しました。このコミュニティのために 、Elixirと関数型プログラミングに関する最も興味深い記事の1つ半をロシア語に翻訳しました。
週の初めに、サイトを更新し、5つの記事を共有しました。 彼らがあなたをいらいらさせ、あなたにその言語を試すよう説得してくれることを願っています。 たとえば、シンプルな冬休みアプリを作成します。 明日は、購読者に公開された記事の完全なセットを送信します。 だから今日サインアップして友達を招待してください 。 このような贈り物を楽しみにしています!
プロジェクトの次のステップは、初心者向けの本格的な紹介を書き、公式ドキュメントを翻訳し、一般的な質問に詳細に答えることです。
- どこから始めますか?
- プロジェクトをデプロイする方法は?
- 使用するエディター
- どのタスクを解決しますか?
その他
来年は、言語自体の急速な動きでいっぱいになります。 ロシア企業への導入。 彼らは言語について知るだけでなく、(可能な限り)それを大規模に使い始めるでしょう。
資料をご覧いただきありがとうございます。 あなたが加入者である場合、あなたの友人を招待してください。
来てすべて!