Skip to content

Commit

Permalink
🥔✨ Journal: Sprout Keywords#show (#1649)
Browse files Browse the repository at this point in the history
* 🥔✨ `Journal`: Sprout `Keywords#show`

- https://github.com/zinc-collective/convene/issues/1566
- https://github.com/zinc-collective/convene/issues/1662

* Show Entries that match a Keyword or it's Aliases

* Use the canonical-keyword when building urls

* `Journal`: Extract `Entry.matching_keywords([...])` scope

* Spiff up the Presentation a touch
  • Loading branch information
zspencer authored Jul 20, 2023
1 parent 2fcb8e2 commit 2bb76ab
Showing 8 changed files with 68 additions and 2 deletions.
2 changes: 2 additions & 0 deletions app/furniture/journal/entry.rb
Original file line number Diff line number Diff line change
@@ -32,6 +32,8 @@ class Entry < ApplicationRecord
has_one :space, through: :journal
before_save :extract_keywords, if: :will_save_change_to_body?

scope :matching_keywords, ->(keywords) { where("keywords::text[] && ARRAY[?]::text[]", keywords) }

def published?
published_at.present?
end
9 changes: 9 additions & 0 deletions app/furniture/journal/keyword.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class Journal
class Keyword < ApplicationRecord
location(parent: :journal)
extend StripsNamespaceFromModelName

self.table_name = "journal_keywords"
validates :canonical_keyword, presence: true, uniqueness: {case_sensitive: false, scope: :journal_id}
@@ -11,6 +12,14 @@ class Keyword < ApplicationRecord
.or(where("lower(canonical_keyword) IN (?)", keywords.map(&:downcase)))
end)

def entries
journal.entries.matching_keywords([canonical_keyword] + (aliases.presence || []))
end

def to_param
canonical_keyword
end

def self.extract_and_create_from!(body)
body.scan(/#(\w+)/)&.flatten&.map do |keyword|
existing_keyword = search(keyword).first
17 changes: 17 additions & 0 deletions app/furniture/journal/keyword_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class Journal
class KeywordPolicy < ApplicationPolicy
alias_method :keyword, :object

def show?
true
end

class Scope < ApplicationScope
def resolve
scope
end
end
end
end
11 changes: 11 additions & 0 deletions app/furniture/journal/keywords/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<h1><%= keyword.canonical_keyword %></h1>
<%- if keyword.aliases.present? %>
<p class="italic">Also known as <%= to_sentence(keyword.aliases) %></p>
<%- end %>

<h2>Entries about <span class="italic"><%= keyword.canonical_keyword %></span></h2>
<ul>
<%- policy_scope(keyword.entries).each do |entry|%>
<li><%= link_to(entry.headline, entry.location) %></li>
<%- end %>
</ul>
11 changes: 11 additions & 0 deletions app/furniture/journal/keywords_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Journal
class KeywordsController < FurnitureController
expose(:keyword, scope: -> { policy_scope(journal.keywords) }, model: Keyword,
find: ->(id, scope) { scope.find_by(canonical_keyword: id) })

expose(:journal, -> { Journal.find(params[:journal_id]) })
def show
authorize(keyword)
end
end
end
5 changes: 3 additions & 2 deletions app/furniture/journal/routes.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class Journal
class Routes
def self.append_routes(router)
router.resources :journals do
router.resources :entries, module: "journal"
router.resources :journals, module: "journal" do
router.resources :entries
router.resources :keywords, only: [:show]
end
end
end
1 change: 1 addition & 0 deletions spec/factories/furniture/journal.rb
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
end

factory :journal_keyword, class: "Journal::Keyword" do
canonical_keyword { Faker::Fantasy::Tolkien.location }
journal
end
end
14 changes: 14 additions & 0 deletions spec/furniture/journal/keywords_controller_request_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require "rails_helper"

RSpec.describe Journal::KeywordsController, type: :request do
describe "#show" do
subject(:perform_request) do
get polymorphic_path(keyword.location)
response
end

let(:keyword) { create(:journal_keyword) }

it { is_expected.to be_ok }
end
end

0 comments on commit 2bb76ab

Please sign in to comment.