From 9e87fddd52e59967f1394efdd9b46f3664977873 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sat, 25 Oct 2025 03:54:04 +0900 Subject: [PATCH 1/5] Let List quack like a model --- app/models/list.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/list.rb b/app/models/list.rb index 4867eb0..c1586f0 100644 --- a/app/models/list.rb +++ b/app/models/list.rb @@ -1,8 +1,11 @@ class List + include ActiveModel::Model + def initialize(name, id) @name = name @id = id end + attr_reader :name, :id # Ordered by the established dates. ruby-list was started in 1995. From 10b8feb4f6086f08b297b43bfbb1636849d538c3 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sat, 25 Oct 2025 03:54:51 +0900 Subject: [PATCH 2/5] url_for(@list) #=> '/ruby-dev' --- app/models/list.rb | 8 ++++++++ config/routes.rb | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/models/list.rb b/app/models/list.rb index c1586f0..31cbcc8 100644 --- a/app/models/list.rb +++ b/app/models/list.rb @@ -27,4 +27,12 @@ def find_by_id(id) alias find find_by_id end + + def to_param + name + end + + def persisted? + true + end end diff --git a/config/routes.rb b/config/routes.rb index 5031106..8188757 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,6 @@ Rails.application.routes.draw do get '/:list_name/:list_seq', to: 'messages#show' - get '/:list_name/', to: 'messages#index' + get '/:list_name/', to: 'messages#index', as: :list get '/attachments/:encoded_key/*filename' => 'attachments#show', as: :attachment From adc2e0ce4e6ac0dcca7e40bf11957957ea5ea2e5 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sat, 25 Oct 2025 03:58:14 +0900 Subject: [PATCH 3/5] Assign @list on messages#show --- app/controllers/messages_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index e9101db..c846177 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -22,8 +22,8 @@ def index # GET /messages/ruby-dev/1 def show - list = List.find_by_name(params[:list_name]) - @message = Message.find_by(list_id: list.id, list_seq: params[:list_seq]) + @list = List.find_by_name(params[:list_name]) + @message = Message.find_by(list_id: @list.id, list_seq: params[:list_seq]) end private From 6fd391f92be8b22096afc71bb7a69c832b7a2e6c Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sat, 25 Oct 2025 04:01:30 +0900 Subject: [PATCH 4/5] List is a model now --- app/controllers/messages_controller.rb | 4 ++-- app/models/message.rb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index c846177..960cc4f 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -6,7 +6,7 @@ def index if (list_name = params[:list_name]) @list = List.find_by_name list_name - messages = Message.with_recursive(parent_and_children: [Message.where(list_id: @list.id, parent_id: nil).order(:id).limit(100), Message.joins('inner join parent_and_children on messages.parent_id = parent_and_children.id')]) + messages = Message.with_recursive(parent_and_children: [Message.where(list_id: @list, parent_id: nil).order(:id).limit(100), Message.joins('inner join parent_and_children on messages.parent_id = parent_and_children.id')]) .joins('inner join parent_and_children on parent_and_children.id = messages.id') @messages = compose_tree(messages) elsif (query = params[:q]) @@ -23,7 +23,7 @@ def index # GET /messages/ruby-dev/1 def show @list = List.find_by_name(params[:list_name]) - @message = Message.find_by(list_id: @list.id, list_seq: params[:list_seq]) + @message = Message.find_by(list_id: @list, list_seq: params[:list_seq]) end private diff --git a/app/models/message.rb b/app/models/message.rb index 2896db4..259650c 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -48,13 +48,13 @@ def from_mail(mail, list, list_seq) # mail.in_reply_to returns strange Array object in some cases (?), so let's use the raw value parent_message_id_header = extract_message_id_from_in_reply_to(mail.header[:in_reply_to]&.value) - self.parent_id = Message.where(list_id: list.id, message_id_header: parent_message_id_header).pick(:id) if parent_message_id_header + self.parent_id = Message.where(list_id: list, message_id_header: parent_message_id_header).pick(:id) if parent_message_id_header if !self.parent_id && (String === mail.references) - self.parent_id = Message.where(list_id: list.id, message_id_header: mail.references).pick(:id) + self.parent_id = Message.where(list_id: list, message_id_header: mail.references).pick(:id) end if !self.parent_id && (Array === mail.references) mail.references.compact.each do |ref| - break if (self.parent_id = Message.where(list_id: list.id, message_id_header: ref).pick(:id)) + break if (self.parent_id = Message.where(list_id: list, message_id_header: ref).pick(:id)) end end From 4895d9822a11e1655700b281e0676c394f0c0ed3 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sat, 25 Oct 2025 10:49:26 +0900 Subject: [PATCH 5/5] Prefer polymorphic routes --- app/models/message.rb | 5 +++++ app/views/messages/_thread.html.erb | 4 ++-- app/views/messages/search.html.erb | 5 ++--- config/routes.rb | 5 +++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/models/message.rb b/app/models/message.rb index 259650c..b110911 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -130,6 +130,11 @@ def list @list ||= List.find(list_id) end + def to_param + #NOTE: This value isn't unique system-wide. Ideally, this should return a combination of list_name and list_seq + list_seq + end + def count_recursively(count = 0) count + 1 + (children&.sum(&:count_recursively) || 0) end diff --git a/app/views/messages/_thread.html.erb b/app/views/messages/_thread.html.erb index 64c8f5e..c9dfea2 100644 --- a/app/views/messages/_thread.html.erb +++ b/app/views/messages/_thread.html.erb @@ -1,6 +1,6 @@
data-controller="thread"<% end %>> <% if depth == 0 %> - <%= link_to "/#{list.name}/#{message.list_seq}", class: 'message-item block bg-white dark:bg-gray-800 rounded-lg shadow-md border border-gray-200 dark:border-gray-700 overflow-hidden hover:shadow-lg transition-shadow', data: {turbo_frame: 'message_content', turbo_action: 'advance', action: 'click->message-list#select'} do %> + <%= link_to [list, message], class: 'message-item block bg-white dark:bg-gray-800 rounded-lg shadow-md border border-gray-200 dark:border-gray-700 overflow-hidden hover:shadow-lg transition-shadow', data: {turbo_frame: 'message_content', turbo_action: 'advance', action: 'click->message-list#select'} do %>
@@ -35,7 +35,7 @@
<% end %> <% else %> - <%= link_to "/#{list.name}/#{message.list_seq}", class: 'message-item block py-2 border-l-2 border-gray-200 dark:border-gray-700 pl-4 hover:border-red-400 dark:hover:border-red-500 transition-colors', data: {turbo_frame: 'message_content', turbo_action: 'advance', action: 'click->message-list#select'} do %> + <%= link_to [list, message], class: 'message-item block py-2 border-l-2 border-gray-200 dark:border-gray-700 pl-4 hover:border-red-400 dark:hover:border-red-500 transition-colors', data: {turbo_frame: 'message_content', turbo_action: 'advance', action: 'click->message-list#select'} do %>
diff --git a/app/views/messages/search.html.erb b/app/views/messages/search.html.erb index 9ab4143..e9a8089 100644 --- a/app/views/messages/search.html.erb +++ b/app/views/messages/search.html.erb @@ -27,10 +27,9 @@ <% @messages.each do |message| %>
- <% list_name = List.find(message.list_id).name %>

- <%= list_name %>:<%= message.list_seq %> - <%= link_to without_list_prefix(message.subject), "/#{list_name}/#{message.list_seq}" %> + <%= message.list.name %>:<%= message.list_seq %> + <%= link_to without_list_prefix(message.subject), [message.list, message] %>

<%= search_snippet(message.body, params[:q]) %>
diff --git a/config/routes.rb b/config/routes.rb index 8188757..309f23c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,8 @@ Rails.application.routes.draw do - get '/:list_name/:list_seq', to: 'messages#show' get '/:list_name/', to: 'messages#index', as: :list - + resources :list, only: [], path: '', param: :name do + resources :messages, only: :show, path: '', param: :list_seq + end get '/attachments/:encoded_key/*filename' => 'attachments#show', as: :attachment # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html