Skip to content

Commit 4a62bbe

Browse files
committed
two way message sending
1 parent 6bae9a9 commit 4a62bbe

19 files changed

+223
-2
lines changed
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class MessagesController < ApplicationController
2+
def index
3+
@reservation = current_user.all_reservations.find(params[:reservation_id])
4+
@messages = @reservation.messages
5+
end
6+
7+
def create
8+
@reservation = current_user.all_reservations.find(message_params[:reservation_id])
9+
@message = current_user.sent_messages.new(message_params)
10+
@message.to_user = @reservation.guest == current_user ? @reservation.host : @reservation.guest
11+
if !@message.save
12+
flash[:errors] = @message.errors.full_messages
13+
end
14+
redirect_to messages_path(reservation_id: @reservation.id)
15+
end
16+
17+
private
18+
19+
def message_params
20+
params.require(:message).permit(:content, :reservation_id)
21+
end
22+
end

app/helpers/messages_helper.rb

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module MessagesHelper
2+
end

app/mailers/message_mailer.rb

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class MessageMailer < ApplicationMailer
2+
3+
# Subject can be set in your I18n file at config/locales/en.yml
4+
# with the following lookup:
5+
#
6+
# en.message_mailer.new_message.subject
7+
#
8+
def new_message
9+
@message = params[:message]
10+
11+
mail to: @message.to_user.email, subject: "New message from #{@message.from_user.email}"
12+
end
13+
end

app/models/message.rb

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Message < ApplicationRecord
2+
belongs_to :from_user, class_name: 'User'
3+
belongs_to :to_user, class_name: 'User'
4+
belongs_to :reservation, optional: true
5+
6+
after_create_commit :notify_to_user
7+
8+
def notify_to_user
9+
NewMessage.with(message: self).deliver_later(to_user)
10+
end
11+
end

app/models/reservation.rb

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Reservation < ApplicationRecord
1818
has_one :host, through: :listing
1919
enum status: {pending: 0, booked: 1, canceling: 3, cancelled: 2, expired: 4}
2020
has_one :calendar_event, dependent: :destroy, required: true
21+
has_many :messages
2122

2223
delegate :start_date, to: :calendar_event
2324
delegate :end_date, to: :calendar_event

app/models/user.rb

+6
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,15 @@ class User < ApplicationRecord
3939
has_many :reservations, foreign_key: :guest_id
4040
has_many :host_reservations, class_name: 'Reservation', through: :listings, source: :reservations
4141
has_many :notifications, as: :recipient
42+
has_many :sent_messages, class_name: 'Message', foreign_key: 'from_user_id'
43+
has_many :received_messages, class_name: 'Message', foreign_key: 'to_user_id'
4244

4345
after_commit :maybe_create_stripe_customer, on: [:create, :update]
4446

47+
def all_reservations
48+
Reservation.where(guest: self).or(Reservation.where(listing: listings))
49+
end
50+
4551
def maybe_create_stripe_customer
4652
return if !stripe_customer_id.blank?
4753

app/notifications/new_message.rb

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# To deliver this notification:
2+
#
3+
# NewMessage.with(message: @message).deliver_later(current_user)
4+
# NewMessage.with(message: @message).deliver(current_user)
5+
6+
class NewMessage < Noticed::Base
7+
# Add your delivery methods
8+
#
9+
deliver_by :database
10+
deliver_by :email, mailer: "MessageMailer", method: :new_message
11+
# deliver_by :slack
12+
# deliver_by :custom, class: "MyDeliveryMethod"
13+
14+
# Add required params
15+
#
16+
param :message
17+
18+
# Define helper methods to make rendering easier.
19+
#
20+
# def message
21+
# t(".message")
22+
# end
23+
#
24+
# def url
25+
# post_path(params[:post])
26+
# end
27+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<h1>New Message</h1>
2+
3+
<p>
4+
<%= @message.content %>
5+
</p>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Message#new_message
2+
3+
<%= @greeting %>, find me in app/views/message_mailer/new_message.text.erb

app/views/messages/index.html.erb

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<h1 class="text-2xl mb-6">Messages</h1>
2+
3+
<div class="flow-root">
4+
<ul role="list" class="-mb-8">
5+
<% @messages.each_with_index do |message, i| %>
6+
<li>
7+
<div class="relative pb-8">
8+
<% if i < @messages.length - 1 %>
9+
<span class="absolute top-5 left-5 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true"></span>
10+
<% end %>
11+
12+
<div class="relative flex items-start space-x-3">
13+
<div class="relative">
14+
<img class="h-10 w-10 rounded-full bg-gray-400 flex items-center justify-center ring-8 ring-white" src="https://images.unsplash.com/photo-1520785643438-5bf77931f493?ixlib=rb-=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=8&w=256&h=256&q=80" alt="">
15+
16+
<span class="absolute -bottom-0.5 -right-1 bg-white rounded-tl px-0.5 py-px">
17+
<!-- Heroicon name: solid/chat-alt -->
18+
<svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
19+
<path fill-rule="evenodd" d="M18 5v8a2 2 0 01-2 2h-5l-5 4v-4H4a2 2 0 01-2-2V5a2 2 0 012-2h12a2 2 0 012 2zM7 8H5v2h2V8zm2 0h2v2H9V8zm6 0h-2v2h2V8z" clip-rule="evenodd" />
20+
</svg>
21+
</span>
22+
</div>
23+
<div class="min-w-0 flex-1">
24+
<div>
25+
<div class="text-sm">
26+
<a href="#" class="font-medium text-gray-900"><%= message.from_user.email %></a>
27+
</div>
28+
<p class="mt-0.5 text-sm text-gray-500">Sent <%= time_ago_in_words(message.created_at) %> ago</p>
29+
</div>
30+
<div class="mt-2 text-sm text-gray-700">
31+
<p><%= message.content %></p>
32+
</div>
33+
</div>
34+
</div>
35+
</div>
36+
</li>
37+
<% end %>
38+
</ul>
39+
</div>
40+
41+
<form action="/messages" method="post" class="mt-6">
42+
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
43+
<input type="hidden" name="message[reservation_id]" value="<%= @reservation.id %>">
44+
<div>
45+
<label for="comment" class="block text-sm font-medium text-gray-700">Add your message</label>
46+
<div class="mt-1">
47+
<textarea rows="4" name="message[content]" id="comment" class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md"></textarea>
48+
</div>
49+
</div>
50+
<div>
51+
<button type="submit" >Send</button>
52+
</div>
53+
</form>

app/views/reservations/show.html.erb

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
<pre><%= JSON.pretty_generate(@reservation.as_json(include: :calendar_event)) %></pre>
44

5+
<%= link_to "Messages", messages_path(reservation_id: @reservation.id) %>
6+
57
<form action="<%= cancel_reservation_path(@reservation) %>" method="post">
68
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
79
<input type="submit" value="Cancel">

config/routes.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
root to: 'static_pages#home'
44

55
resources :listings, only: [:index, :show]
6+
resources :messages, only: [:index, :create]
67
resources :reservations do
78
member do
89
post '/cancel' => 'reservations#cancel'
@@ -12,7 +13,6 @@
1213
post '/webhooks/:source' => 'webhooks#create'
1314

1415
namespace :host do
15-
get 'reservations/show'
1616
resources :merchant_settings do
1717
collection do
1818
get :connect, to: 'merchant_settings#connect'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class CreateMessages < ActiveRecord::Migration[7.0]
2+
def change
3+
create_table :messages do |t|
4+
t.references :from_user, null: false, foreign_key: { to_table: :users }
5+
t.references :to_user, null: false, foreign_key: { to_table: :users }
6+
t.references :reservation, null: true, foreign_key: true
7+
t.string :content, null: false, default: ''
8+
9+
t.timestamps
10+
end
11+
end
12+
end

db/schema.rb

+16-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
require "test_helper"
2+
3+
class MessagesControllerTest < ActionDispatch::IntegrationTest
4+
test "should get index" do
5+
get messages_index_url
6+
assert_response :success
7+
end
8+
end

test/fixtures/messages.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2+
3+
one:
4+
from_user: one
5+
to_user: one
6+
reservation: one
7+
content: MyString
8+
9+
two:
10+
from_user: two
11+
to_user: two
12+
reservation: two
13+
content: MyString

test/mailers/message_mailer_test.rb

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
require "test_helper"
2+
3+
class MessageMailerTest < ActionMailer::TestCase
4+
test "new_message" do
5+
mail = MessageMailer.new_message
6+
assert_equal "New message", mail.subject
7+
assert_equal ["[email protected]"], mail.to
8+
assert_equal ["[email protected]"], mail.from
9+
assert_match "Hi", mail.body.encoded
10+
end
11+
12+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Preview all emails at http://localhost:3000/rails/mailers/message_mailer
2+
class MessageMailerPreview < ActionMailer::Preview
3+
4+
# Preview this email at http://localhost:3000/rails/mailers/message_mailer/new_message
5+
def new_message
6+
MessageMailer.new_message
7+
end
8+
9+
end

test/models/message_test.rb

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
require "test_helper"
2+
3+
class MessageTest < ActiveSupport::TestCase
4+
# test "the truth" do
5+
# assert true
6+
# end
7+
end

0 commit comments

Comments
 (0)