Compare commits

...

10 Commits

Author SHA1 Message Date
Trevor Vallender 6f32112b2a Use new authenticate_by method 2023-10-20 11:19:09 +01:00
Trevor Vallender 5d0a1b1612 Add migrations to post-deploy hook 2023-10-20 11:19:04 +01:00
Trevor Vallender e0c12a9760 Use default Rails healthcheck 2023-10-20 10:38:55 +01:00
Trevor Vallender fe197ebe9a Gruvbox colour updates 2023-10-19 21:33:44 +01:00
Trevor Vallender 059d59e437 Set up Solid Cache 2023-10-19 20:28:18 +01:00
Trevor Vallender b7bbd85c7e Bugfix: Wasn’t splitting tags! 2023-10-19 20:15:04 +01:00
Trevor Vallender 1d9efa6cab View microposts by tag 2023-10-19 20:00:01 +01:00
Trevor Vallender d5b587499c Tag refinements
- Don’t allow duplicates
- Allow edits correctly
2023-10-19 19:36:08 +01:00
Trevor Vallender 6358e2a61e Show tags in microposts 2023-10-19 19:10:20 +01:00
Trevor Vallender ad03410a65 Method to add tags to microposts 2023-10-19 18:46:41 +01:00
23 changed files with 166 additions and 14 deletions

View File

@ -12,3 +12,4 @@
# KAMAL_RUNTIME # KAMAL_RUNTIME
echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds" echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds"
kamal app exec --reuse "bin/rails db:migrate"

View File

@ -15,6 +15,7 @@ gem "bcrypt", "~> 3.1.7"
gem "bootsnap", require: false gem "bootsnap", require: false
gem "kaminari" # Pagination gem "kaminari" # Pagination
gem "solid_cache"
group :development, :test do group :development, :test do
gem "debug", platforms: %i[ mri mingw x64_mingw ] gem "debug", platforms: %i[ mri mingw x64_mingw ]

View File

@ -229,6 +229,8 @@ GEM
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0) rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0) websocket (~> 1.0)
solid_cache (0.1.0)
rails (>= 7)
sprockets (4.2.1) sprockets (4.2.1)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
rack (>= 2.2.4, < 4) rack (>= 2.2.4, < 4)
@ -281,6 +283,7 @@ DEPENDENCIES
puma puma
rails (~> 7.1) rails (~> 7.1)
selenium-webdriver selenium-webdriver
solid_cache
sprockets-rails sprockets-rails
stimulus-rails stimulus-rails
turbo-rails turbo-rails

View File

@ -1,11 +1,11 @@
:root { :root {
--border-color: gray; --border-color: #282828;
--highlight-color: #D36200; --highlight-color: #d65d0e;
--background-color: #CCC; --background-color: #928374;
--dark-background-color: #333; --dark-background-color: #1d2021;
--inset-background-color: #FFFFFF; --inset-background-color: #fbf1c7;
--alert-border-color: #800000; --alert-border-color: #98971a;
--form-error-color: #FF0000; --form-error-color: #cc241d;
} }
* { * {

View File

@ -23,6 +23,10 @@ form#micropost_form {
} }
} }
ul#microposts {
list-style-type: none;
}
.micropost { .micropost {
margin: 1em auto; margin: 1em auto;
padding: .5em; padding: .5em;
@ -33,4 +37,16 @@ form#micropost_form {
text-align: right; text-align: right;
font-size: .8em; font-size: .8em;
} }
h5 {
display: inline;
}
ul.micropost-tags {
list-style-type: none;
display: inline;
li {
display: inline;
}
}
} }

View File

@ -17,6 +17,7 @@ class MicropostsController < ApplicationController
def create def create
micropost = Micropost.new(micropost_params) micropost = Micropost.new(micropost_params)
micropost.user = helpers.current_user micropost.user = helpers.current_user
micropost.set_tags(*parse_tags(params[:tags])) if params[:tags]
if micropost.save if micropost.save
redirect_to micropost, notice: t(".created") redirect_to micropost, notice: t(".created")
else else
@ -29,6 +30,7 @@ class MicropostsController < ApplicationController
def edit; end def edit; end
def update def update
@micropost.set_tags(*parse_tags(params[:tags])) if params[:tags]
if @micropost.update(micropost_params) if @micropost.update(micropost_params)
redirect_to @micropost, notice: t(".updated") redirect_to @micropost, notice: t(".updated")
else else
@ -46,6 +48,10 @@ class MicropostsController < ApplicationController
private private
def parse_tags(tags)
tags.split
end
def micropost_params def micropost_params
params.require(:micropost).permit( params.require(:micropost).permit(
:content, :content,

View File

@ -9,7 +9,8 @@ class SessionsController < ApplicationController
def new; end def new; end
def create def create
if @user.present? && @user.authenticate(params[:password]) @user = User.authenticate_by(username: params[:username], password: params[:password])
if @user
session[:user_id] = @user.id session[:user_id] = @user.id
redirect_to root_path, notice: t(".logged_in") redirect_to root_path, notice: t(".logged_in")
else else

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class TagsController < ApplicationController
skip_before_action :require_login, only: [:index, :show]
before_action :set_tag, only: [:show]
def index
@tags = Tag.all
.page(params[:page])
end
def show; end
private
def set_tag
@tag = Tag.find_by(name: params[:id])
end
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
module MicropostsHelper
def tag_string(micropost)
micropost.tags.map(&:name).join(" ")
end
end

View File

@ -10,4 +10,11 @@ class Micropost < ApplicationRecord
has_many :microposts_tags has_many :microposts_tags
has_many :tags, through: :microposts_tags has_many :tags, through: :microposts_tags
def set_tags(*tag_names)
tag_names.each do |tag_name|
tag = Tag.find_or_create_by(name: tag_name)
tags << tag unless tags.include?(tag)
end
end
end end

View File

@ -4,4 +4,8 @@ class Tag < ApplicationRecord
validates :name, presence: true validates :name, presence: true
has_many :microposts_tags has_many :microposts_tags
has_many :microposts, through: :microposts_tags has_many :microposts, through: :microposts_tags
def to_param
name
end
end end

View File

@ -3,5 +3,7 @@
<%= f.rich_text_area :content %> <%= f.rich_text_area :content %>
<%= text_field_tag :tags, tag_string(@micropost) %>
<%= f.submit button_text %> <%= f.submit button_text %>
<% end %> <% end %>

View File

@ -1,5 +1,13 @@
<div class="micropost"> <div class="micropost">
<%= micropost.content %> <%= micropost.content %>
<% unless micropost.tags.empty? %>
<h5>Tags:</h5>
<ul id="micropost-<%= micropost.id %>-tags" class="micropost-tags">
<% micropost.tags.each do |tag| %>
<li><%= link_to tag.name, tag %></li>
<% end %>
</ul>
<% end %>
<div class="created_at"> <div class="created_at">
<%= link_to "Edit", edit_micropost_path(micropost) if micropost.user == current_user %> <%= link_to "Edit", edit_micropost_path(micropost) if micropost.user == current_user %>
<%= link_to micropost.created_at.strftime("%Y-%m-%d %H:%M"), micropost %> <%= link_to micropost.created_at.strftime("%Y-%m-%d %H:%M"), micropost %>

View File

@ -0,0 +1,12 @@
<h2><%= t(".tags") %></h2>
<% if @tags.empty? %>
<p><%= t(".empty") %></p>
<% else %>
<ul id="tags">
<% @tags.each do |tag| %>
<li><%= link_to tag.name, tag %></li>
<% end %>
</ul>
<%= paginate @tags %>
<% end %>

View File

@ -0,0 +1,3 @@
<h2><%= @tag.name %></h2>
<%= render @tag.microposts %>

View File

@ -52,7 +52,3 @@ builder:
remote: remote:
arch: arm64 arch: arm64
host: ssh://kamal@tsvallender.co.uk host: ssh://kamal@tsvallender.co.uk
healthcheck:
path: /sessions/new
port: 3000

View File

@ -56,7 +56,7 @@ Rails.application.configure do
config.log_tags = [ :request_id ] config.log_tags = [ :request_id ]
# Use a different cache store in production. # Use a different cache store in production.
# config.cache_store = :mem_cache_store config.cache_store = :solid_cache_store
# Use a real queuing backend for Active Job (and separate queues per environment). # Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque # config.active_job.queue_adapter = :resque

View File

@ -0,0 +1,6 @@
en:
tags:
index:
tags: Tags
empty: You dont have any tags yet

View File

@ -14,4 +14,7 @@ Rails.application.routes.draw do
resources :blog_posts resources :blog_posts
resources :microposts resources :microposts
resources :tags, only: [:index, :show]
get "up" => "rails/health#show", as: :rails_health_check
end end

View File

@ -0,0 +1,12 @@
# This migration comes from solid_cache (originally 20230724121448)
class CreateSolidCacheEntries < ActiveRecord::Migration[7.0]
def change
create_table :solid_cache_entries do |t|
t.binary :key, null: false, limit: 1024
t.binary :value, null: false, limit: 512.megabytes
t.datetime :created_at, null: false
t.index :key, unique: true
end
end
end

9
db/schema.rb generated
View File

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.1].define(version: 2023_10_19_172703) do ActiveRecord::Schema[7.1].define(version: 2023_10_19_192600) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -77,6 +77,13 @@ ActiveRecord::Schema[7.1].define(version: 2023_10_19_172703) do
t.index ["tag_id", "micropost_id"], name: "index_microposts_tags_on_tag_id_and_micropost_id" t.index ["tag_id", "micropost_id"], name: "index_microposts_tags_on_tag_id_and_micropost_id"
end end
create_table "solid_cache_entries", force: :cascade do |t|
t.binary "key", null: false
t.binary "value", null: false
t.datetime "created_at", null: false
t.index ["key"], name: "index_solid_cache_entries_on_key", unique: true
end
create_table "tags", force: :cascade do |t| create_table "tags", force: :cascade do |t|
t.string "name", null: false t.string "name", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false

View File

@ -0,0 +1,21 @@
require "test_helper"
class TagMicropostsTest < ActionDispatch::IntegrationTest
test "tags can be added to microposts" do
@user = users(:trevor)
sign_in(@user)
get new_micropost_path
assert_response :success
post microposts_path, params: {
micropost: {
content: "An interesting post",
},
tags: "foo bar baz",
}
assert_response :redirect
follow_redirect!
assert_includes response.body, "foo"
assert_includes response.body, "bar"
assert_includes response.body, "baz"
end
end

View File

@ -17,4 +17,21 @@ class MicropostTest < ActiveSupport::TestCase
@micropost.content = nil @micropost.content = nil
assert_not @micropost.valid? assert_not @micropost.valid?
end end
test "can add tags" do
assert_empty @micropost.tags
assert_difference "@micropost.tags.count", +3 do
@micropost.set_tags("foo", "bar", "baz")
end
end
test "duplicate tags are not added" do
assert_empty @micropost.tags
assert_difference "@micropost.tags.count", +3 do
@micropost.set_tags("foo", "bar", "baz")
end
assert_no_difference "@micropost.tags.count" do
@micropost.set_tags("bar", "baz")
end
end
end end