How to implement a favorite icon on separate pictures of a carousel using Ruby on Rails (v.7)?

55 Views Asked by At

1

I have a photo sharing app built on rails that allows users to like, comment and favorite each other's pictures.

If a user uploads multiple pictures/videos at once, these are shown in a carousel (using bootstrap 5.2). I'm trying to add a favorite icon to each separate post within a carousel.

For now, if a user favorites a carousel, it will save all pictures/videos that are part of it, whereas I want to allow users to only save the unique picture or video they would like to have.

Any direction on how to implement this is really appreciated!

These are some snippets of my code:

My Routes

  resources :events do
    resources :attachments, only: [:new, :create, :index, :destroy]
  end

  resources :attachments, except: [:index, :new, :create, :destroy] do
    resources :comments, only: [:create, :edit, :update]
    resources :likes, only: :create
    resources :favorites, only: :create
  end
  resources :comments, only: [:destroy]
  resources :likes, only: :destroy
  resources :favorites, only: :destroy
end

Attachment model

class Attachment < ApplicationRecord
belongs_to :event
belongs_to :user
has_many :comments, dependent: :destroy
has_many :likes, dependent: :destroy
has_many_attached :posts
has_many :favorites, dependent: :destroy

validates :posts, presence: true
end

Favorite model

class Favorite < ApplicationRecord
belongs_to :attachment
belongs_to :user
validates :user_id, uniqueness: { scope: :attachment_id}
end

Attachment show page

<div class="attachment-post">
              <% if @attachment.posts.attached? %>
                <% if @attachment.posts.length > 1 %>
                  <div id="carouselExampleIndicators" class="carousel slide" data-bs-ride="true">
                    <div class="carousel-indicators">
                      <% @attachment.posts.each_with_index do |post, index| %>
                      <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="<%="#{index}" %>" class="<%= index.zero? ? "active" : nil %>", aria-current="<%= index.zero? ? "true" : nil %>" aria-label="Slide <%="#{index}" %>"></button>
                      <% end %>
                    </div>

                    <div class="carousel-inner">
                      <% @attachment.posts.each_with_index do |post, index| %>
                        <div class="carousel-item <%= index.zero? ? "active" : nil %>">
                          <% if post.content_type.include?("image") %>
                            <%= cl_image_tag post.key, class:"img-event-gallery d-block w-100", crop: :fill %>
                          <% else %>
                            <%= cl_video_tag post.key, controls: true, class:"img-event-gallery d-block w-100", crop: :fill %>
                          <% end %>
                        </div>
                        <button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide="prev">
                          <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                          <span class="visually-hidden">Previous</span>
                        </button>
                        <button class="carousel-control-next" type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide="next">
                          <span class="carousel-control-next-icon" aria-hidden="true"></span>
                          <span class="visually-hidden">Next</span>
                        </button>
                      <% end %>
                    </div>
                  </div>
                <% else %>
                  <% if @attachment.posts[0].content_type.include?("image") %>
                    <%= cl_image_tag @attachment.posts[0].key, class:"img-event-gallery", crop: :fill %>
                  <% else %>
                    <%= cl_video_tag @attachment.posts[0].key, controls: true, class:"img-event-gallery", crop: :fill%>
                  <% end %>
                <% end %>
              <% else %>
                <h3>Upload your images by clicking on the plus sign</h3>
              <% end %>
            </div>

            <div class="post-content">
              <div class="like-and-delete-and-favorite d-flex justify-content-between">
                <div class = "likes-icon d-flex justify-content-start" >
                  <div class="likes-icon-number">
                    <p class="likes"><%= pluralize(@attachment.likes.count, "Like") %>
                      <% like = current_user.likes.find_by(attachment: @attachment) %>
                    <% if current_user %>
                      <% if like.nil? %>
                        <%= link_to  attachment_likes_path(@attachment), data: {turbo_method: :post}, class:"likes-icons" do %>
                          <i class="fa-regular fa-heart"></i>
                        <% end %>
                      <% else %>

                        <%= link_to like_path(like), data: {turbo_method: :delete}, class:"likes-icons" do %>
                          <i class="fa-solid fa-heart"></i>
                        <% end %>
                      <% end %>
                    <% else %>
                      <%# signup %>
                        <%= link_to attachment_likes_path(@attachment), data: {turbo_method: :post},
                          class:"likes-icons" do %>
                          <i class="fa-regular fa-heart"></i>
                        <% end %>
                    <% end %>
                  </div>
                  <div class="favorite-icon">
                  <% favorite = current_user.favorites.find_by(attachment: @attachment) %>
                  <% if current_user %>
                    <% if favorite.nil? %>
                      <%= link_to  attachment_favorites_path(@attachment), data: {turbo_method: :post}, class:"favorites-icons" do %>
                        <i class="fa-regular fa-bookmark"></i>
                      <% end %>
                    <% else %>

                      <%= link_to favorite_path(favorite), data: {turbo_method: :delete}, class:"favorites-icons" do %>
                        <i class="fa-solid fa-bookmark"></i>
                      <% end %>
                    <% end %>
                  <% else %>
                    <%# signup %>
                      <%= link_to attachment_favorites_path(@attachment), data: {turbo_method: :post},
                        class:"favorites-icons" do %>
                        <i class="fa-regular fa-bookmark"></i>
                      <% end %>
                  <% end %>
                  </div>
                </div>
              </div>

when the picture is not added to favorites :

<a data-turbo-method="post" class="favorites-icons" href="/attachments/7/favorites"> 
  <i class="fa-regular fa-bookmark"></i> 
</a> 

vs when it is added to favorites:

<a data-turbo-method="delete" class="favorites-icons" href="/favorites/59"> 
  <i class="fa-solid fa-bookmark"></i> 
</a>
0

There are 0 best solutions below