diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index ec84559..2c38c38 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -3,12 +3,26 @@ class MessagesController < ApplicationController # GET /messages or /messages.json def index - @messages = Message.all + query = params[:q] + if query + # %> and <-> are defined by pg_trgm. + # https://www.postgresql.org/docs/17/pgtrgm.html + @messages = Message.find_by_sql([ + 'SELECT * FROM messages WHERE body %> ? ORDER BY body <-> ? LIMIT 20', + query, query, + ]) + else + @messages = Message.all + end end # GET /messages/1 or /messages/1.json def show - @message = Message.from_s3(params[:list_name], params[:list_seq]) + if params[:id] + @message = Message.find(params[:id]) + else + @message = Message.from_s3(params[:list_name], params[:list_seq]) + end end # GET /messages/new diff --git a/app/models/message.rb b/app/models/message.rb index 87d0bf4..56c9368 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -9,7 +9,7 @@ def self.from_s3(list_name, list_seq) end def self.from_string(str) - hs, body = str.split(/\n\n/, 2) + hs, body = str.encode('utf-8', invalid: :replace).split(/\n\n/, 2) headers = hs.split(/\n/).map { |line| line.split(/:\s+/, 2) }.to_h diff --git a/app/views/messages/index.html.erb b/app/views/messages/index.html.erb index 809266a..0d32916 100644 --- a/app/views/messages/index.html.erb +++ b/app/views/messages/index.html.erb @@ -2,13 +2,13 @@

Messages

-
+
+ <%= link_to "New message", new_message_path %> diff --git a/db/migrate/20240810063115_add_pg_trgm.rb b/db/migrate/20240810063115_add_pg_trgm.rb new file mode 100644 index 0000000..9629962 --- /dev/null +++ b/db/migrate/20240810063115_add_pg_trgm.rb @@ -0,0 +1,5 @@ +class AddPgTrgm < ActiveRecord::Migration[7.1] + def change + enable_extension 'pg_trgm' + end +end diff --git a/db/migrate/20240810064037_add_trigram_index.rb b/db/migrate/20240810064037_add_trigram_index.rb new file mode 100644 index 0000000..291a602 --- /dev/null +++ b/db/migrate/20240810064037_add_trigram_index.rb @@ -0,0 +1,15 @@ +class AddTrigramIndex < ActiveRecord::Migration[7.1] + def up + # According to https://www.postgresql.org/docs/9.1/textsearch-indexes.html + # + # > As a rule of thumb, GIN indexes are best for static data because + # > lookups are faster. For dynamic data, GiST indexes are faster to update. + # + # So we use GIN here instead of GiST. + add_index(:messages, :body, using: :gin, opclass: { body: :gin_trgm_ops }) + end + + def down + remove_index(:messages, :body) + end +end diff --git a/db/schema.rb b/db/schema.rb index 3330b7b..fcde555 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,13 +10,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_08_10_040807) do +ActiveRecord::Schema[7.1].define(version: 2024_08_10_064037) do create_table "messages", force: :cascade do |t| t.string "subject" t.string "from" t.text "body" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["body"], name: "index_messages_on_body" end end