We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Post 32
Blog Site 03 - Updates to make it feel better
Published on: 2025-06-01
Tags:
elixir, Blog, Side Project, Ecto, Authorization, Fly, Deployment
Today I wanted to change these things on my blog site: 1. Only I can make a post but anyone can add comments. 2. Add in a better home page to tell my story. 3. Change the look of the posts. 4. Change the look of the post index. 5. Change the links that are seen when: not logged in, logged in, an admin. 1. Add Admin to the users. This required a few things that needed to be taken care of. First and foremost I needed to add a admin to the user table to check for. mix ecto.gen.migration add_admin_to_users This will add and other migration def change do alter table(:users) do add :admin, :boolean, default: false, null: false end end This will alter the table so that we can add in a admin colmun mix ecto.migrate This will update the database. Once that was done I needed to change the user schema def registration_changeset(user, attrs, opts \\ []) do user |> cast(attrs, [:email, :password, :admin]) # added in the :admin |> validate_email(opts) |> validate_password(opts) end Now we need to be sure that things that need you to be an Admin will have the check plug :require_admin when action in [:new, :create, :edit, :update, :delete] # put at the top of any page that needs admin requirement defp require_admin(conn, _opts) do if conn.assigns.current_user && conn.assigns.current_user.admin do conn else conn |> put_flash(:error, "Unauthorized") |> redirect(to: Routes.page_path(conn, :index)) |> halt() end end This is the plug utilization. Okay now we have the tests and admin column we now need to make sure that a user can be set by the admin. def update_admin(%User{} = user) do user |> Ecto.Changeset.change(%{admin: true}) |> Repo.update() end This is a very brute force method as it will just take a user and make them an Admin. As you will only be able to run this as someone that owns the site it will work. Okay so Ill go over this real quick in 2 ways: On your own localhost: iex -S mix phx.server # To get in the server with the iex console user = Blog.Accounts.get_user!(1) # Get the user Blog.Accounts.update_admin(user) # Make them an admin On your fly.io fly ssh console # Get into the fly console app/bin/blog remote # Get into the app Blog.Accounts.get_user!(1) |> Blog.Accounts.update_admin() Now this is assuming that you have run the migration or the recent deployment ran a migration. Just in case you haven't done that here is those steps: fly ssh console -C "/app/bin/blog eval 'Blog.Release.migrate()'" This should run the deployment. 2. Add a better home page. This is a bit more general but in the end I made sure to have some references to the work that I have done and added some better styling. Here is a link, <a href="https://www.hackerrank.com/" target="_blank" style="color: #007acc; text-decoration: none;">HackerRank</a>, Here is a link that has a "link" icon 🔗 <a href="https://game-site.fly.dev/" target="_blank" style="color: #007acc; font-weight: bold;">Game Site</a><br> 3. Change the look of the posts. This was a small but having less on the screen can help with the clarity. Also I'll say this now any time you want to be sure that an item will only be seen by an admin you can add. <%= if @current_user.admin do %> ... <% end %> # This will check to be sure that the person is an Admin. I also wanted to have the tags, and published on smaller and on the same line. <div class="max-w-6xl mx-auto p-8 bg-white shadow rounded"> <!-- Title --> <div> <h1 class="text-3xl font-bold text-gray-900 mb-2">{@post.title}</h1> <div class="text-sm text-gray-500 flex flex-wrap gap-4"> <span>Published on: <span class="text-gray-700">{@post.published_on}</span></span> <span>Tags: <span class="text-gray-700"> <%= Enum.map(@post.tags, & &1.name) |> Enum.join(", ") %> </span> </span> </div> </div> 4. This is an other one that took some more padding, and some other small changes. 5. One more time I'll post it here again, if you want to check for an Admin (html) you simply can add this around an html item. <%= if @current_user.admin do %> ... <% end %>
