https://github.com/Samuel-Lubliner/Belay-Board-Simple
https://github.com/users/Samuel-Lubliner/projects/2
Post and delete comments on availabilities
Now that I have a calendar with availabilities, add Description and comments, I want to allow users to post and delete comments on availabilities. Comments made by the user who cerated the availability will be displayed as a description section. Comments made by guests will be displayed under the description as a comment section.
rails g model Comment body:text user:references availability:references
rails db:migrate
Associations
class Comment < ApplicationRecord
belongs_to :user
belongs_to :availability
validates :body, presence: true
end
class Availability < ApplicationRecord
#...
has_many :comments, dependent: :destroy
end
class User < ApplicationRecord
#...
has_many :comments, dependent: :destroy
end
rails g controller Comments
class CommentsController < ApplicationController
before_action :set_availability, only: [:create]
before_action :set_comment, only: [:destroy]
def create
@comment = @availability.comments.new(comment_params)
@comment.user = current_user
if @comment.save
redirect_to @availability, notice: 'Comment was successfully added.'
else
redirect_to @availability, alert: 'Unable to add comment.'
end
end
def destroy
@comment.destroy
redirect_to @comment.availability, notice: 'Comment was successfully deleted.'
end
private
def set_availability
@availability = Availability.find(params[:availability_id])
end
def set_comment
@comment = current_user.comments.find(params[:id])
end
def comment_params
params.require(:comment).permit(:body, :availability_id)
end
end
Rails.application.routes.draw do
root "availabilities#index"
devise_for :users
resources :availabilities do
resources :comments, only: [:create, :destroy]
end
resources :event_requests, only: [:create] do
member do
post :accept
post :reject
end
end
<div class="container mt-3">
<div class="row">
<div class="col-md-8">
<%= render @availability %>
<% if current_user && @availability.user != current_user %>
<% unless @availability.event_requests.exists?(user: current_user) %>
<%= form_for(current_user.event_requests.new, url: event_requests_path, remote: true, class: 'd-flex justify-content-end') do |f| %>
<%= f.hidden_field :availability_id, value: @availability.id %>
<%= button_tag(type: "submit", class: "btn btn-primary", id: "join-event-button") do %>
<i class="fas fa-user-plus"></i>Me
<% end %>
<% end %>
<% end %>
<% end %>
<p>
<strong>Guests</strong>
</p>
<ul id="guest_requests_list" class="list-group">
<% @event_requests.each do |event_request| %>
<li id="event_request_<%= event_request.id %>" class="list-group-item d-flex justify-content-between align-items-center">
<%= render partial: 'event_request', locals: { event_request: event_request } %>
<% if event_request.status == 'pending' && @availability.user == current_user %>
<%= button_to 'Accept', accept_event_request_path(event_request), method: :post, remote: true, class: 'btn btn-success btn-sm', data: { turbo: false } %>
<%= button_to 'Reject', reject_event_request_path(event_request), method: :post, remote: true, class: 'btn btn-danger btn-sm', data: { turbo: false } %>
<% end %>
</li>
<% end %>
</ul>
<h3>Description</h3>
<div class="card mb-3">
<div class="card-body">
<% @availability.comments.each do |comment| %>
<% if comment.user == @availability.user %>
<div class="d-flex justify-content-between">
<p><%= comment.body %></p>
<% if current_user == comment.user %>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton<%= comment.id %>" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton<%= comment.id %>">
<li>
<%= button_to 'Delete',
availability_comment_path(@availability, comment),
method: :delete,
data: { confirm: 'Are you sure?' },
class: 'dropdown-item' %>
</li>
</ul>
</div>
<% end %>
</div>
<% end %>
<% end %>
</div>
</div>
<h3>Comments</h3>
<div class="card mb-3">
<div class="card-body">
<% @availability.comments.each do |comment| %>
<% unless comment.user == @availability.user %>
<div class="d-flex justify-content-between">
<p><strong><%= comment.user.username %>:</strong> <%= comment.body %></p>
<% if current_user == comment.user %>
<% end %>
</div>
<% end %>
<% end %>
</div>
</div>
<%= form_for([@availability, @availability.comments.new], html: { class: "mb-3" }) do |f| %>
<div class="form-group">
<%= f.text_area :body, class: "form-control", rows: 3 %>
</div>
<% if current_user == @availability.user %>
<div class="form-group d-flex justify-content-end">
<%= f.button 'Description<i class="fas fa-paper-plane"></i>'.html_safe, type: :submit, class: "btn btn-primary" %>
</div>
<% else %>
<div class="form-group d-flex justify-content-end">
<%= f.button 'Comment<i class="fas fa-paper-plane"></i>'.html_safe, type: :submit, class: "btn btn-primary" %>
</div>
<% end %>
<% end %>
</div>
<div class="col-md-4">
<div class="dropdown">
<a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fas fa-cog"></i>
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<li><%= link_to "Edit this availability", edit_availability_path(@availability), class: 'dropdown-item' %></li>
<li><%= button_to "Destroy this availability", @availability, method: :delete, class: 'dropdown-item', data: { confirm: 'Are you sure?' } %></li>
</ul>
</div>
</div>
</div>
</div>
Next Steps
Now that I have a calendar to display the index of availabilities, I will develop a calendar with filtering for availabilities where the user is a the event creator and availabilities where the user is a guest. I will also implement a dashboard for guest status.
Top comments (0)