DEV Community

Samuel Lubliner
Samuel Lubliner

Posted on

Belay Board Simple Part 3: Comments

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
<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>
Enter fullscreen mode Exit fullscreen mode

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.

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay