Skip to content

Commit fd73a6d

Browse files
committed
feat(elixir:gsmlg): Add blog module.
1 parent a16a73f commit fd73a6d

File tree

18 files changed

+648
-3
lines changed

18 files changed

+648
-3
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
defmodule GSMLG.Content do
2+
@moduledoc """
3+
The Content context.
4+
"""
5+
6+
import Ecto.Query, warn: false
7+
alias GSMLG.Repo
8+
9+
alias GSMLG.Content.Blog
10+
11+
@doc """
12+
Returns the list of blogs.
13+
14+
## Examples
15+
16+
iex> list_blogs()
17+
[%Blog{}, ...]
18+
19+
"""
20+
def list_blogs do
21+
Repo.all(Blog)
22+
end
23+
24+
@doc """
25+
Gets a single blog.
26+
27+
Raises `Ecto.NoResultsError` if the Blog does not exist.
28+
29+
## Examples
30+
31+
iex> get_blog!(123)
32+
%Blog{}
33+
34+
iex> get_blog!(456)
35+
** (Ecto.NoResultsError)
36+
37+
"""
38+
def get_blog!(id), do: Repo.get!(Blog, id)
39+
40+
@doc """
41+
Creates a blog.
42+
43+
## Examples
44+
45+
iex> create_blog(%{field: value})
46+
{:ok, %Blog{}}
47+
48+
iex> create_blog(%{field: bad_value})
49+
{:error, %Ecto.Changeset{}}
50+
51+
"""
52+
def create_blog(attrs \\ %{}) do
53+
%Blog{}
54+
|> Blog.changeset(attrs)
55+
|> Repo.insert()
56+
end
57+
58+
@doc """
59+
Updates a blog.
60+
61+
## Examples
62+
63+
iex> update_blog(blog, %{field: new_value})
64+
{:ok, %Blog{}}
65+
66+
iex> update_blog(blog, %{field: bad_value})
67+
{:error, %Ecto.Changeset{}}
68+
69+
"""
70+
def update_blog(%Blog{} = blog, attrs) do
71+
blog
72+
|> Blog.changeset(attrs)
73+
|> Repo.update()
74+
end
75+
76+
@doc """
77+
Deletes a blog.
78+
79+
## Examples
80+
81+
iex> delete_blog(blog)
82+
{:ok, %Blog{}}
83+
84+
iex> delete_blog(blog)
85+
{:error, %Ecto.Changeset{}}
86+
87+
"""
88+
def delete_blog(%Blog{} = blog) do
89+
Repo.delete(blog)
90+
end
91+
92+
@doc """
93+
Returns an `%Ecto.Changeset{}` for tracking blog changes.
94+
95+
## Examples
96+
97+
iex> change_blog(blog)
98+
%Ecto.Changeset{data: %Blog{}}
99+
100+
"""
101+
def change_blog(%Blog{} = blog, attrs \\ %{}) do
102+
Blog.changeset(blog, attrs)
103+
end
104+
end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
defmodule GSMLG.Content.Blog do
2+
use Ecto.Schema
3+
import Ecto.Changeset
4+
5+
schema "blogs" do
6+
field :author, :string
7+
field :content, :string
8+
field :date, :date
9+
field :slug, :string
10+
field :title, :string
11+
12+
timestamps()
13+
end
14+
15+
@doc false
16+
def changeset(blog, attrs) do
17+
blog
18+
|> cast(attrs, [:slug, :title, :date, :author, :content])
19+
|> validate_required([:slug, :title, :date, :author, :content])
20+
end
21+
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
defmodule GSMLG.Repo.Migrations.CreateBlogs do
2+
use Ecto.Migration
3+
4+
def change do
5+
create table(:blogs) do
6+
add :slug, :string
7+
add :title, :string
8+
add :date, :date
9+
add :author, :string
10+
add :content, :text
11+
12+
timestamps()
13+
end
14+
end
15+
end
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
defmodule GSMLG.ContentTest do
2+
use GSMLG.DataCase
3+
4+
alias GSMLG.Content
5+
6+
describe "blogs" do
7+
alias GSMLG.Content.Blog
8+
9+
import GSMLG.ContentFixtures
10+
11+
@invalid_attrs %{author: nil, content: nil, date: nil, slug: nil, title: nil}
12+
13+
test "list_blogs/0 returns all blogs" do
14+
blog = blog_fixture()
15+
assert Content.list_blogs() == [blog]
16+
end
17+
18+
test "get_blog!/1 returns the blog with given id" do
19+
blog = blog_fixture()
20+
assert Content.get_blog!(blog.id) == blog
21+
end
22+
23+
test "create_blog/1 with valid data creates a blog" do
24+
valid_attrs = %{author: "some author", content: "some content", date: ~D[2021-09-26], slug: "some slug", title: "some title"}
25+
26+
assert {:ok, %Blog{} = blog} = Content.create_blog(valid_attrs)
27+
assert blog.author == "some author"
28+
assert blog.content == "some content"
29+
assert blog.date == ~D[2021-09-26]
30+
assert blog.slug == "some slug"
31+
assert blog.title == "some title"
32+
end
33+
34+
test "create_blog/1 with invalid data returns error changeset" do
35+
assert {:error, %Ecto.Changeset{}} = Content.create_blog(@invalid_attrs)
36+
end
37+
38+
test "update_blog/2 with valid data updates the blog" do
39+
blog = blog_fixture()
40+
update_attrs = %{author: "some updated author", content: "some updated content", date: ~D[2021-09-27], slug: "some updated slug", title: "some updated title"}
41+
42+
assert {:ok, %Blog{} = blog} = Content.update_blog(blog, update_attrs)
43+
assert blog.author == "some updated author"
44+
assert blog.content == "some updated content"
45+
assert blog.date == ~D[2021-09-27]
46+
assert blog.slug == "some updated slug"
47+
assert blog.title == "some updated title"
48+
end
49+
50+
test "update_blog/2 with invalid data returns error changeset" do
51+
blog = blog_fixture()
52+
assert {:error, %Ecto.Changeset{}} = Content.update_blog(blog, @invalid_attrs)
53+
assert blog == Content.get_blog!(blog.id)
54+
end
55+
56+
test "delete_blog/1 deletes the blog" do
57+
blog = blog_fixture()
58+
assert {:ok, %Blog{}} = Content.delete_blog(blog)
59+
assert_raise Ecto.NoResultsError, fn -> Content.get_blog!(blog.id) end
60+
end
61+
62+
test "change_blog/1 returns a blog changeset" do
63+
blog = blog_fixture()
64+
assert %Ecto.Changeset{} = Content.change_blog(blog)
65+
end
66+
end
67+
end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
defmodule GSMLG.ContentFixtures do
2+
@moduledoc """
3+
This module defines test helpers for creating
4+
entities via the `GSMLG.Content` context.
5+
"""
6+
7+
@doc """
8+
Generate a blog.
9+
"""
10+
def blog_fixture(attrs \\ %{}) do
11+
{:ok, blog} =
12+
attrs
13+
|> Enum.into(%{
14+
author: "some author",
15+
content: "some content",
16+
date: ~D[2021-09-26],
17+
slug: "some slug",
18+
title: "some title"
19+
})
20+
|> GSMLG.Content.create_blog()
21+
22+
blog
23+
end
24+
end

elixir/gsmlg_umbrella/apps/gsmlg_web/lib/gsmlg_web.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ defmodule GSMLGWeb do
8383

8484
# Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc)
8585
import Phoenix.LiveView.Helpers
86+
import GSMLGWeb.LiveHelpers
8687

8788
# Import basic rendering functionality (render, render_layout, etc)
8889
import Phoenix.View
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
defmodule GSMLGWeb.BlogLive.FormComponent do
2+
use GSMLGWeb, :live_component
3+
4+
alias GSMLG.Content
5+
6+
@impl true
7+
def update(%{blog: blog} = assigns, socket) do
8+
changeset = Content.change_blog(blog)
9+
10+
{:ok,
11+
socket
12+
|> assign(assigns)
13+
|> assign(:changeset, changeset)}
14+
end
15+
16+
@impl true
17+
def handle_event("validate", %{"blog" => blog_params}, socket) do
18+
changeset =
19+
socket.assigns.blog
20+
|> Content.change_blog(blog_params)
21+
|> Map.put(:action, :validate)
22+
23+
{:noreply, assign(socket, :changeset, changeset)}
24+
end
25+
26+
def handle_event("save", %{"blog" => blog_params}, socket) do
27+
save_blog(socket, socket.assigns.action, blog_params)
28+
end
29+
30+
defp save_blog(socket, :edit, blog_params) do
31+
case Content.update_blog(socket.assigns.blog, blog_params) do
32+
{:ok, _blog} ->
33+
{:noreply,
34+
socket
35+
|> put_flash(:info, "Blog updated successfully")
36+
|> push_redirect(to: socket.assigns.return_to)}
37+
38+
{:error, %Ecto.Changeset{} = changeset} ->
39+
{:noreply, assign(socket, :changeset, changeset)}
40+
end
41+
end
42+
43+
defp save_blog(socket, :new, blog_params) do
44+
case Content.create_blog(blog_params) do
45+
{:ok, _blog} ->
46+
{:noreply,
47+
socket
48+
|> put_flash(:info, "Blog created successfully")
49+
|> push_redirect(to: socket.assigns.return_to)}
50+
51+
{:error, %Ecto.Changeset{} = changeset} ->
52+
{:noreply, assign(socket, changeset: changeset)}
53+
end
54+
end
55+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<div>
2+
<h2><%= @title %></h2>
3+
4+
<.form
5+
let={f}
6+
for={@changeset}
7+
id="blog-form"
8+
phx-target={@myself}
9+
phx-change="validate"
10+
phx-submit="save">
11+
12+
<%= label f, :slug %>
13+
<%= text_input f, :slug %>
14+
<%= error_tag f, :slug %>
15+
16+
<%= label f, :title %>
17+
<%= text_input f, :title %>
18+
<%= error_tag f, :title %>
19+
20+
<%= label f, :date %>
21+
<%= date_select f, :date %>
22+
<%= error_tag f, :date %>
23+
24+
<%= label f, :author %>
25+
<%= text_input f, :author %>
26+
<%= error_tag f, :author %>
27+
28+
<%= label f, :content %>
29+
<%= textarea f, :content %>
30+
<%= error_tag f, :content %>
31+
32+
<div>
33+
<%= submit "Save", phx_disable_with: "Saving..." %>
34+
</div>
35+
</.form>
36+
</div>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
defmodule GSMLGWeb.BlogLive.Index do
2+
use GSMLGWeb, :live_view
3+
4+
alias GSMLG.Content
5+
alias GSMLG.Content.Blog
6+
7+
@impl true
8+
def mount(_params, _session, socket) do
9+
{:ok, assign(socket, :blogs, list_blogs())}
10+
end
11+
12+
@impl true
13+
def handle_params(params, _url, socket) do
14+
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
15+
end
16+
17+
defp apply_action(socket, :edit, %{"id" => id}) do
18+
socket
19+
|> assign(:page_title, "Edit Blog")
20+
|> assign(:blog, Content.get_blog!(id))
21+
end
22+
23+
defp apply_action(socket, :new, _params) do
24+
socket
25+
|> assign(:page_title, "New Blog")
26+
|> assign(:blog, %Blog{})
27+
end
28+
29+
defp apply_action(socket, :index, _params) do
30+
socket
31+
|> assign(:page_title, "Listing Blogs")
32+
|> assign(:blog, nil)
33+
end
34+
35+
@impl true
36+
def handle_event("delete", %{"id" => id}, socket) do
37+
blog = Content.get_blog!(id)
38+
{:ok, _} = Content.delete_blog(blog)
39+
40+
{:noreply, assign(socket, :blogs, list_blogs())}
41+
end
42+
43+
defp list_blogs do
44+
Content.list_blogs()
45+
end
46+
end

0 commit comments

Comments
 (0)