Skip to content

Instantly share code, notes, and snippets.

@bearded-avenger
Last active July 2, 2020 15:50
Show Gist options
  • Save bearded-avenger/5b462f1ee841cf241d3ffbeadb2117f1 to your computer and use it in GitHub Desktop.
Save bearded-avenger/5b462f1ee841cf241d3ffbeadb2117f1 to your computer and use it in GitHub Desktop.
Bookmarking in Rails
# In a View
<%= render 'bookmarks/add_remove', record: @lesson %>
# The Partial
<% if current_customer && current_customer.bookmarked_content?(record) %>
<%= button_to bookmark_path(current_customer.bookmark_for_content(record), bookmarkable_type:record.class.name, bookmarkable_id:record.id), method: :delete, class:'btn btn-sm btn-light box-shadow', form_class:'add-remove-bookmark', data:{disable_with:'Removing...'}, remote: true do %>
<%= ms_icon('minus-circle', title:'Unsave This') %>
<% end %>
<% else %>
<%= button_to bookmarks_path(bookmarkable_type:record.class.name, bookmarkable_id:record.id), method: :post, class:'btn btn-sm btn-light box-shadow', form_class:'add-remove-bookmark', data:{disable_with:'Adding...'}, remote: true do %>
<%= ms_icon('plus-circle', title:'Save This') %>
<% end %>
<% end %>
class BookmarksController < ApplicationController
BOOKMARKABLES = {
'Course' => Course,
'Lesson' => Lesson,
'Post' => Post,
'LiveStream' => LiveStream,
'Download' => Download
}
before_action :set_bookmark, :set_authorized_editor, only: :destroy
before_action :find_bookmarkable, only: :create
before_action :redirect_if_plugin_not_activated, :authenticate_customer!
# POST /bookmarks
def create
@bookmark = @bookmarkable.bookmarks.new
@bookmark.user = current_user
@bookmark.customer = current_customer
respond_to do |format|
if @bookmark.save
format.html {redirect_to polymorphic_path(@bookmark.bookmarkable), success: 'Bookmark was successfully created.'}
format.js
else
format.html {redirect_to polymorphic_path(@bookmark.bookmarkable), danger: 'Bookmark not created.'}
format.js
end
end
end
# DELETE /bookmarks/1
def destroy
respond_to do |format|
if @bookmark.destroy
format.html {redirect_to polymorphic_path(@bookmark.bookmarkable), success: 'Bookmark was successfully destroyed.'}
format.js
else
format.html {redirect_to polymorphic_path(@bookmark.bookmarkable), danger: 'Bookmark not destroyed.'}
format.js
end
end
end
private
def set_bookmark
@bookmark = Bookmark.find(params[:id])
end
def find_bookmarkable
if params[:bookmarkable_type].present?
klass = BOOKMARKABLES.fetch(params[:bookmarkable_type])
@bookmarkable = klass.find(params[:bookmarkable_id])
end
end
def set_authorized_editor
redirect_to polymorphic_path(@bookmark.bookmarkable) unless (
( current_customer && (current_customer == @bookmark.customer) ) ||
( current_user && (current_user == @bookmark.user) ) ||
( current_user && current_user.can_access_site?(current_tenant) )
)
end
def redirect_if_plugin_not_activated
redirect_to site_root_path unless current_tenant.plugin_activated?('bookmarks')
end
end
$('.add-remove-bookmark').replaceWith("<%= j render partial: 'bookmarks/add_remove', locals:{record:@bookmark.bookmarkable} %>")
class Customer < ApplicationRecord
def bookmarked_content?(content)
bookmarks.exists?(bookmarkable:content)
end
def bookmark_for_content(content)
bookmarks.find_by(bookmarkable:content)
end
end
@bearded-avenger
Copy link
Author

bearded-avenger commented Jul 2, 2020

These methods are custom and not part of Rails.

ms_icon is a custom helper method that draws a single svg icon
current_customer and current_user is provide by Devise
current_tenant is provided by ActsAsTenant
plugin_activated? is a custom method that checks to see if a tenant has a plugin activated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment