Current section
Files
Jump to
Current section
Files
lib/thesis/stores/ecto_store.ex
defmodule Thesis.EctoStore do
@moduledoc """
Thesis.EctoStore is the most commonly-used store for Thesis pages and content.
It interfaces with the host application's repo (which is provided in the
config.exs of the host applicaton).
You can generally just use Thesis.EctoStore unless you're not using Ecto in
your project or you want to do something custom with how Thesis is handling
its data.
"""
@behaviour Thesis.Store
import Thesis.Config
alias Thesis.{ Page, PageContent }
def page(slug) when is_binary(slug) do
repo.get_by(Page, slug: slug)
end
def page_contents(nil), do: []
def page_contents(slug) when is_binary(slug) do
page_contents(page(slug))
end
def page_contents(%Page{id: page_id}) do
repo.all(PageContent, page_id: [nil, page_id])
end
def update(%{"slug" => slug} = page_params, contents_params) do
page = page(slug) || %Page{slug: slug}
page_changeset = Ecto.Changeset.cast(page, page_params, [], ~w(slug title description redirect_url template) )
repo.insert_or_update!(page_changeset)
contents_params
|> Enum.map(fn(x) -> content_changeset(x, page, page_contents(page)) end)
|> Enum.map(fn(x) -> repo.insert_or_update!(x) end)
:ok
end
def delete(%{"slug" => slug}) do
page = page(slug)
repo.delete!(page)
:ok
end
defp content_changeset(new_contents, page, preloaded_contents) do
%{ "name" => name, "content" => content, "content_type" => content_type } = new_contents
page_id = page_id_or_global(new_contents, page)
page_content = PageContent.find(preloaded_contents, page_id, name) ||
%PageContent{page_id: page_id, name: name}
updated_properties = %{content: content, content_type: content_type, meta: new_contents["meta"]}
Ecto.Changeset.cast(page_content, updated_properties, ~w(content content_type meta), [])
end
defp page_id_or_global(%{"global" => "true"}, _page), do: nil
defp page_id_or_global(_content, %Thesis.Page{id: id}), do: id
end