From 3378bc606528600c25568c2b1ae376b9ae1cddb8 Mon Sep 17 00:00:00 2001 From: Jessica Phoenix Canady Date: Tue, 24 Sep 2024 12:31:41 -0400 Subject: [PATCH] Mostly get db-based posts up and running. --- lib/jol/blog.ex | 31 +++++++++++++++++-- lib/jol/blog/post.ex | 4 ++- lib/jol/blog/{tags.ex => tag.ex} | 4 ++- lib/jol_web/controllers/blog_html/show.heex | 4 +-- .../controllers/page_html/home.html.heex | 2 +- lib/jol_web/controllers/tag_controller.ex | 10 +++--- .../controllers/tag_html/index.html.heex | 2 +- .../controllers/tag_html/tag.html.heex | 2 +- lib/jol_web/router.ex | 2 +- mix.exs | 3 +- priv/migrate_posts.exs | 26 ++++++++++++++++ .../20240924153630_join_posts_and_tags.exs | 10 ++++++ .../20240924154328_make_tag_name_unique.exs | 8 +++++ 13 files changed, 92 insertions(+), 16 deletions(-) rename lib/jol/blog/{tags.ex => tag.ex} (67%) create mode 100644 priv/migrate_posts.exs create mode 100644 priv/repo/migrations/20240924153630_join_posts_and_tags.exs create mode 100644 priv/repo/migrations/20240924154328_make_tag_name_unique.exs diff --git a/lib/jol/blog.ex b/lib/jol/blog.ex index e718e92..692c6fb 100644 --- a/lib/jol/blog.ex +++ b/lib/jol/blog.ex @@ -1,5 +1,7 @@ defmodule JOL.Blog do - alias JOL.Blog.Post + alias JOL.Blog.{Post, Tag} + alias JOL.Repo + import Ecto.Query defmodule NotFoundError do defexception [:message, plug_status: 404] @@ -10,17 +12,40 @@ defmodule JOL.Blog do end def unique_tag_list do - [] + Repo.all(Tag, order_by: :name) end def recent_posts(num \\ 10) do - [] + Repo.all( + from p in Post, + limit: ^num, + order_by: {:desc, :published_at} + ) end def get_post_by_slug!(slug) do + Repo.one( + from p in Post, + where: [slug: ^slug], + preload: [:tags] + ) end def get_posts_by_tag!(tag) do + Repo.all( + from p in Post, + join: t in assoc(p, :tags), + preload: [tags: t], + where: t.name == ^tag + ) + end + + def get_tag_by_id!(id) do + Repo.one( + from t in Tag, + where: t.id == ^id, + preload: [:posts] + ) end def format_date(date) do diff --git a/lib/jol/blog/post.ex b/lib/jol/blog/post.ex index 0e03b1f..7d125fe 100644 --- a/lib/jol/blog/post.ex +++ b/lib/jol/blog/post.ex @@ -7,6 +7,7 @@ defmodule JOL.Blog.Post do field :body, :string field :published_at, :naive_datetime field :slug, :string + many_to_many :tags, JOL.Blog.Tag, join_through: "post_tags" timestamps(type: :utc_datetime) end @@ -15,6 +16,7 @@ defmodule JOL.Blog.Post do def changeset(post, attrs) do post |> cast(attrs, [:title, :body, :published_at, :slug]) - |> validate_required([:title, :body, :published_at, :slug]) + |> validate_required([:title, :body, :slug]) + |> cast_assoc(:tags) end end diff --git a/lib/jol/blog/tags.ex b/lib/jol/blog/tag.ex similarity index 67% rename from lib/jol/blog/tags.ex rename to lib/jol/blog/tag.ex index ff67e17..826dfe6 100644 --- a/lib/jol/blog/tags.ex +++ b/lib/jol/blog/tag.ex @@ -1,9 +1,10 @@ -defmodule JOL.Blog.Tags do +defmodule JOL.Blog.Tag do use Ecto.Schema import Ecto.Changeset schema "tags" do field :name, :string + many_to_many :posts, JOL.Blog.Post, join_through: "post_tags" timestamps(type: :utc_datetime) end @@ -13,5 +14,6 @@ defmodule JOL.Blog.Tags do tags |> cast(attrs, [:name]) |> validate_required([:name]) + |> unique_constraint([:name]) end end diff --git a/lib/jol_web/controllers/blog_html/show.heex b/lib/jol_web/controllers/blog_html/show.heex index a7c8a1f..791a160 100644 --- a/lib/jol_web/controllers/blog_html/show.heex +++ b/lib/jol_web/controllers/blog_html/show.heex @@ -3,11 +3,11 @@

<%= @post.title %>

- <%= JOL.Blog.format_date(@post.date) %> + <%= JOL.Blog.format_date(@post.published_at) %>

<%= raw @post.body %>

- Filed under: <%= Enum.join(@post.tags, ", ") %> + Filed under: <%= @post.tags |> Enum.map(& &1.name) |> Enum.join(", ") %>

diff --git a/lib/jol_web/controllers/page_html/home.html.heex b/lib/jol_web/controllers/page_html/home.html.heex index 4c451e3..3a8256a 100644 --- a/lib/jol_web/controllers/page_html/home.html.heex +++ b/lib/jol_web/controllers/page_html/home.html.heex @@ -12,7 +12,7 @@