From acda77ed7cb67116c9f990fd5466f54ad303877f Mon Sep 17 00:00:00 2001 From: goravbhootra Date: Thu, 14 Nov 2019 08:14:32 +0530 Subject: [PATCH] added documentation to README --- README.md | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) diff --git a/README.md b/README.md index 4297df2..10d0b0e 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,223 @@ Dlex.alter(conn, [ ]) ``` +### Usage in Phoenix App + +#### Enable database connection and add to supervision tree + +The example below uses `Grepo` instead of `Repo` to enable use of dgraph along with another database. If dgraph is the only database required for the project, then the changes can be made directly in `repo.ex`: + +```elixir +defmodule App.Grepo do + use Dlex.Repo, + otp_app: :app, + modules: [App.Courses.Course] +end +``` + +In application.ex: + +```elixir +def start(_type, _args) do + # List all child processes to be supervised + children = [ + # Start the Ecto repository + App.Repo, + # Start the endpoint when the application starts + AppWeb.Endpoint, + # Starts a worker by calling: App.Worker.start_link(arg) + # {App.Worker, arg}, + App.Grepo, + ] + ... +end +``` + +#### Define a model + +```elixir +defmodule App.Courses.Course do + use Dlex.Node + @derive {Phoenix.Param, key: :uid} + + import Ecto.Changeset + + schema "courses" do + field(:title, :string, index: ["term"]) + field(:description, :string) + field(:guidelines, :string) + field(:status, :integer) + field(:has_learning_path, :uid) + end + + @doc false + def changeset(course, attrs) do + course + |> cast(attrs, [ + :title, + :description, + :guidelines, + :status, + :has_learning_path + ]) +end + +``` + +#### Update the schema + +```bash +$ iex -S mix + +# To view the schema: +iex> Grepo.snapshot() + +# To execute the update (alter_schema uses snapshot() by default and can be omitted) +iex> Grepo.snapshot() |> Grepo.alter_schema() + +``` + +#### Define the context + +This follows the same pattern as a regular phoenix app context with the above setup: + +```elixir +defmodule App.Courses do + @moduledoc """ + The Courses context. + """ + + alias App.Grepo + alias App.Courses.Course + + ... + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking course changes. + + ## Examples + + iex> change_course(course) + %Ecto.Changeset{source: %Course{}} + + """ + def change_course(%Course{} = course) do + Course.changeset(course, %{}) + end + + @doc """ + Creates a course. + + ## Examples + + iex> create_course(%{field: value}) + {:ok, %Course{}} + + iex> create_course(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_course(attrs \\ %{}) do + %Course{} + |> Course.changeset(attrs) + |> Grepo.set() + end + + ... + + def course_statuses() do + [ + {"Published", 1}, + {"Unpublished", 2} + ] + end + + ... +end +``` + +#### Define the controller + +```elixir +defmodule AppWeb.Admin.CourseController do + use AppWeb, :controller + + alias App.Grepo + alias App.Courses + alias App.Courses.Course + + def index(conn, _params) do + query = "{courses(func: type(courses)) {uid expand(_all_)}}" + {:ok, %{"courses" => courses}} = Grepo.all(query) + render(conn, "index.html", courses: courses) + end + + def show(conn, %{"id" => id}) do + course = Grepo.get!(id) + render(conn, "show.html", course: course) + end + + def new(conn, _params) do + changeset = Courses.change_course(%Course{}) + + render(conn, "new.html", + changeset: changeset, + statuses: course_statuses_for_select() + ) + end + + def create(conn, %{"course" => course_params}) do + case Courses.create_course(course_params) do + {:ok, _course} -> + render_success( + conn, + "Course created successfully", + Routes.admin_course_path(conn, :index) + ) + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, "new.html", + changeset: changeset, + statuses: course_statuses_for_select() + ) + end + end + + def edit(conn, %{"id" => id}) do + course = Grepo.get!(id) + changeset = Courses.change_course(course) + + render(conn, "edit.html", + course: course, + changeset: changeset, + statuses: course_statuses_for_select() + ) + end + + def update(conn, %{"id" => id, "course" => course_params}) do + course = Grepo.get!(id) + + case Courses.update_course(course, course_params) do + {:ok, course} -> + render_success( + conn, + "Course updated successfully", + Routes.admin_course_path(conn, :show, course) + ) + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, "edit.html", + course: course, + changeset: changeset, + statuses: course_statuses_for_select() + ) + end + end + + defp course_statuses_for_select, do: Courses.course_statuses() +end +``` + ## Developers guide ### Running tests