Reputation: 2218
class FavoritePhoto < ActiveRecord::Base
belongs_to :user
belongs_to :photo
validates :user_id, uniqueness: {
scope: [:photo_id],
message: 'can only favorite an item once'
}
end
PhotosController
def favorite
@photo = Photo.find(params[:id])
if request.put?
current_user.favorites << @photo
redirect_to :back, notice: 'You successfully favorited this photo'
else request.delete?
current_user.favorites.delete(@photo)
redirect_to :back, notice: 'You successfully unfavorited this photo'
end
end
<%= link_to favorite_photo_path("#{photo.id}"), method: :put do %>
<span class="glyphicon glyphicon-heart"></span>
<% end %>
resources :photos do
match :favorite, on: :member, via: [:put, :delete]
end
This works in preventing the User from favoriting the same photo more than once and the error message "User can only favorite an item once" shows up in my Heroku log, however, when they attempt to favorite a photo twice there is no redirect and message explaining to the User what has happened, it just times out at favorite_photo_path('#{photo.id}").
Upvotes: 0
Views: 119
Reputation: 2218
def favorite
@photo = Photo.find params[:id]
if request.put?
response = current_user.favorite_photos.new(photo: @photo)
if !response.valid?
redirect_to :back
flash[:danger] = "You have already favorited this photo"
else
response.save
redirect_to :back
flash[:success] = "You have successfully favorited this photo"
end
else request.delete?
current_user.favorites.delete(@photo)
redirect_to :back, notice: 'You successfully unfavorited this photo'
end
end
This is the only one I have gotten to work thus far.
Upvotes: 1
Reputation: 76784
The issue is that you're relying on ActiveRecord
validations to populate your view, when they're separate layers of abstraction.
You will need to include some sort of conditional logic to determine whether the @photo
passes the validations you've set:
#app/controllers/photos_controller.rb
class PhotosController < ApplicationController
def favorite
@photo = Photo.find params[:id]
response = current_user.favorites << @photo if request.put?
response = current_user.favorites.delete @photo if request.delete?
if response.valid?
message = response.errors.full_messages.first
else
message = request.put? ? "You have successfully favourited this photo" : "You have successfully unfavourited this photo"
end
redirect_to @photo, notice: message
end
end
Upvotes: 0
Reputation: 5633
I'm not totally sure the best approach is to perform a delete and an update in the same action, but if you'd like to do it this way, you could do something like:
User
has_many :favorite_photos
PhotosController
def favorite
@photo = Photo.find(params[:id])
if request.put?
favorite = current_user.favorite_photos.new(photo: @photo)
if favorite.save
redirect_to :back, notice: 'You successfully favorited this photo'
else
redirect_to photo_path(@photo), notice: favorite.errors.full_messages
end
else request.delete?
current_user.favorites.delete(@photo)
redirect_to :back, notice: 'You successfully unfavorited this photo'
end
end
Upvotes: 0