Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🥔✨ Journal: extract Terms from Entrys #1633

Merged
merged 4 commits into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/furniture/journal/entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Entry < ApplicationRecord
belongs_to :journal, inverse_of: :entries
has_one :room, through: :journal
has_one :space, through: :journal
zspencer marked this conversation as resolved.
Show resolved Hide resolved
after_save :extract_keywords, if: :saved_change_to_body?

def published?
published_at.present?
Expand All @@ -50,6 +51,10 @@ def self.renderer
)
end

def extract_keywords
journal.keywords.extract_and_create_from!(body)
end

def to_param
slug
end
Expand Down
1 change: 1 addition & 0 deletions app/furniture/journal/journal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ class Journal::Journal < Furniture

extend StripsNamespaceFromModelName
has_many :entries, inverse_of: :journal, dependent: :destroy
has_many :keywords, inverse_of: :journal, dependent: :destroy
end
18 changes: 18 additions & 0 deletions app/furniture/journal/keyword.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Journal
class Keyword < ApplicationRecord
location(parent: :journal)

self.table_name = "journal_keywords"
validates :canonical_keyword, presence: true, uniqueness: {case_sensitive: false, scope: :journal_id}
belongs_to :journal, inverse_of: :keywords

def self.extract_and_create_from!(body)
body.scan(/#(\w+)/)&.flatten&.each do |keyword|
next if where(":aliases = ANY (aliases)", aliases: keyword)
.or(where(canonical_keyword: keyword)).exists?

find_or_create_by!(canonical_keyword: keyword)
end
end
end
end
10 changes: 10 additions & 0 deletions db/migrate/20230704064303_add_journal_keywords.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class AddJournalKeywords < ActiveRecord::Migration[7.0]
def change
create_table :journal_keywords, id: :uuid do |t|
t.references :journal, type: :uuid, foreign_key: {to_table: :furnitures}
t.string :canonical_keyword
t.string :aliases, array: true
t.timestamps
end
end
end
10 changes: 10 additions & 0 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@
t.index ["journal_id"], name: "index_journal_entries_on_journal_id"
end

create_table "journal_keywords", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "journal_id"
t.string "canonical_keyword"
t.string "aliases", array: true
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["journal_id"], name: "index_journal_keywords_on_journal_id"
end

create_table "marketplace_cart_products", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "cart_id"
t.uuid "product_id"
Expand Down Expand Up @@ -276,6 +285,7 @@
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "journal_entries", "furnitures", column: "journal_id"
add_foreign_key "journal_keywords", "furnitures", column: "journal_id"
add_foreign_key "marketplace_cart_products", "marketplace_orders", column: "cart_id"
add_foreign_key "marketplace_cart_products", "marketplace_products", column: "product_id"
add_foreign_key "marketplace_delivery_areas", "furnitures", column: "marketplace_id"
Expand Down
24 changes: 20 additions & 4 deletions spec/furniture/journal/entry_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,29 @@
describe "#to_html" do
subject(:to_html) { entry.to_html }

let(:entry) { build(:journal_entry, body: body) }

context "when #body is 'https://www.google.com @[email protected]'" do
let(:body) { "https://www.google.com @[email protected]" }
let(:entry) { build(:journal_entry, body: "https://www.google.com @[email protected]") }

it { is_expected.to include('<a href="https://weirder.earth/@zee">@[email protected]</a>') }
it { is_expected.to include('<a href="https://www.google.com">https://www.google.com</a>') }
end
end

describe "#save" do
let(:entry) { create(:journal_entry, body: "#GoodTimes") }
let(:journal) { entry.journal }

context "when the body is changing" do
it "idempotently creates `Keywords` in the `Journal`" do
bad_apple = entry.journal.keywords.create!(canonical_keyword: "BadApple", aliases: ["BadApples"])
good_times = entry.journal.keywords.find_by!(canonical_keyword: "GoodTimes")
expect do
entry.update!(body: "#GoodTimes #HardCider #BadApples")
end.not_to change { "#{bad_apple.reload.updated_at} - #{good_times.reload.updated_at}" }

expect(journal.keywords.where(canonical_keyword: "GoodTimes")).to exist
expect(journal.keywords.where(canonical_keyword: "HardCider")).to exist
expect(journal.keywords.where(canonical_keyword: "BadApples")).not_to exist
end
end
end
end
1 change: 1 addition & 0 deletions spec/furniture/journal/journal_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

RSpec.describe Journal::Journal, type: :model do
it { is_expected.to have_many(:entries).inverse_of(:journal).dependent(:destroy) }
it { is_expected.to have_many(:keywords).inverse_of(:journal).dependent(:destroy) }
end
9 changes: 9 additions & 0 deletions spec/furniture/journal/keyword_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe Journal::Keyword, type: :model do
it { is_expected.to validate_presence_of(:canonical_keyword) }
it { is_expected.to validate_uniqueness_of(:canonical_keyword).case_insensitive.scoped_to(:journal_id) }
it { is_expected.to belong_to(:journal).inverse_of(:keywords) }
end