Reputation: 2218
The web user has a modal open with a picture showing, they click on:
photos/show.html.erb
<%= link_to favorite_photo_path("#{photo.id}"), method: :put do %>
<span class="glyphicon glyphicon-heart"></span>
<% end %>
The end goal is to keep the user inside of the modal, with a message shown inside of the modal, "You have successfully favorited this photo"... I am testing this out in the middle of the controller where I call respond_to do...
However, when the glyphicon is clicked the model is updated however browser ends up stuck on www.examples.com/photos/1/favorite
Routes
resources :photos do
match :favorite, on: :member, via: [:put, :delete]
end
PhotosController
def favorite
@photo = Photo.find params[:id]
if request.put?
response = current_user.favorite_photos.new(photo: @photo)
if !response.valid?
redirect_to :back, notice: response.errors.full_messages
else
response.save
respond_to do |format|
format.js
end
end
else request.delete?
current_user.favorites.delete(@photo)
redirect_to :back, notice: 'You successfully unfavorited this photo'
end
end
photos/favorite.js.erb
$('.modal-dialog.photo>.message').html('You have successfully favorited this photo');
When html { redirect_to :back } is used, it closes the modal.
Upvotes: 0
Views: 749
Reputation: 3578
To utilize the JavaScript response, you will need to add the remote: true
option to your link.
http://guides.rubyonrails.org/working_with_javascript_in_rails.html
If you want to handle this via AJAX, don't use redirect back.
Also use flash.now
for AJAX.
Instead handle both scenarios in you're JavaScript file.
# app/views/photos/favorite.js.erb
<% if flash.now[:notice] %>
$('.modal-dialog.photo>.message').html("<%= j flash.now[:notice] %>")
<% else %>
$('.modal-dialog.photo>.message').html("<%= j flash.now[:alert] %>")
<% end %>
# app/views/photo/unfavorite.js.erb
<% if flash.now[:notice] %>
$('.modal-dialog.photo>.message').html("<%= j flash.now[:notice] %>")
<% end %>
It kind of goes that notice
is like success and alert
are error.
And change your controller to this:
def favorite
@photo = Photo.find params[:id]
favorite_photo = current_user.favorites.build(photo: @photo)
if favorite_photo.save
flash.now[:notice] = 'You successfully favorited this photo'
else
flash.now[:alert] = favorite_photo.errors.full_messages
end
respond_to :js
end
def unfavorite
@photo = Photo.find params[:id]
current_user.favorites.delete(@photo)
flash.now[:notice] = 'You successfully unfavorited this photo'
respond_to :js
end
And your routes to match this configuration.
I'd POST
to favorite and DELETE
to unfavorite due to the DB implications of each.
Currently you can only pass notice
and alert
to a render
or redirect_to
. But you can defined your own flash types. But don't constrain yourself by using only these two.
if success
flash[:success] = "Something good"
else
flash[:error] = "Something bad"
end
Upvotes: 1