Current section

Files

Jump to
ja_serializer lib mix tasks ja_serializer.gen.phx_api.ex
Raw

lib/mix/tasks/ja_serializer.gen.phx_api.ex

if Code.ensure_loaded?(Phoenix) and Code.ensure_loaded?(Mix.Phoenix.Context) do
defmodule Mix.Tasks.JaSerializer.Gen.PhxApi do
@shortdoc "Generates a controller and model for a JSON API based resource"
use Mix.Task
alias Mix.Phoenix.Context
alias Mix.Tasks.Phx.Gen
def run(args) do
if Mix.Project.umbrella?() do
Mix.raise(
"mix phx.gen.json can only be run inside an application directory"
)
end
{context, schema} = Gen.Context.build(args)
binding = [context: context, schema: schema]
paths = generator_paths()
prompt_for_conflicts(context)
context
|> copy_new_files(paths, binding)
|> print_shell_instructions()
end
defp generator_paths do
[
".",
Mix.Project.deps_path() |> Path.join("..") |> Path.expand(),
:ja_serializer,
:phoenix
]
end
defp prompt_for_conflicts(context) do
context
|> files_to_be_generated()
|> Kernel.++(context_files(context))
|> Mix.Phoenix.prompt_for_conflicts()
end
defp context_files(%Context{generate?: true} = context) do
Gen.Context.files_to_be_generated(context)
end
defp context_files(%Context{generate?: false}) do
[]
end
def files_to_be_generated(%Context{schema: schema, context_app: context_app}) do
web_prefix = Mix.Phoenix.web_path(context_app)
test_prefix = Mix.Phoenix.web_test_path(context_app)
web_path = to_string(schema.web_path)
[
{:new_eex, "changeset_view.ex",
Path.join([web_prefix, "views/changeset_view.ex"])},
{:new_eex, "fallback_controller.ex",
Path.join([web_prefix, "controllers/fallback_controller.ex"])}
]
end
def ja_serializer_files_to_be_generated(%Context{
schema: schema,
context_app: context_app
}) do
web_prefix = Mix.Phoenix.web_path(context_app)
test_prefix = Mix.Phoenix.web_test_path(context_app)
web_path = to_string(schema.web_path)
[
{:eex, "controller.ex",
Path.join([
web_prefix,
"controllers",
web_path,
"#{schema.singular}_controller.ex"
])},
{:eex, "view.ex",
Path.join([web_prefix, "views", web_path, "#{schema.singular}_view.ex"])},
{:eex, "controller_test.exs",
Path.join([
test_prefix,
"controllers",
web_path,
"#{schema.singular}_controller_test.exs"
])}
]
end
def copy_new_files(%Context{} = context, paths, binding) do
files = files_to_be_generated(context)
Mix.Phoenix.copy_from(
paths,
"priv/templates/phx.gen.json",
binding,
files
)
files = ja_serializer_files_to_be_generated(context)
Mix.Phoenix.copy_from(
paths,
"priv/templates/ja_serializer.gen.phx_api",
binding,
files
)
if context.generate?,
do: Gen.Context.copy_new_files(context, paths, binding)
context
end
def print_shell_instructions(
%Context{schema: schema, context_app: ctx_app} = context
) do
if schema.web_namespace do
Mix.shell().info("""
Add the resource to your #{schema.web_namespace} :api scope in #{
Mix.Phoenix.web_path(ctx_app)
}/router.ex:
scope "/#{schema.web_path}", #{
inspect(Module.concat(context.web_module, schema.web_namespace))
} do
pipe_through :api
...
resources "/#{schema.plural}", #{inspect(schema.alias)}Controller
end
""")
else
Mix.shell().info("""
Add the resource to your :api scope in lib/#{Mix.Phoenix.otp_app()}/web/router.ex:
resources "/#{schema.plural}", #{inspect(schema.alias)}Controller, except: [:new, :edit]
""")
end
if context.generate?, do: Gen.Context.print_shell_instructions(context)
end
end
end