
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>