Acts As Bookmarkable Plugin

This is my latest installment on Ruby on Rails plugins. Here is a rails plugin which can help your user manage bookmarks of model records. A bookmarkable model can be any ActiveRecord class so you can use the acts_as_bookmarkable to bookmark other users in a friends list, or bookmark posts in a favorites list, etc. And following the Web 2.0 trends, bookmarks themselves can act as taggable so that you can label bookmarks with tags. You need to install the acts_as_taggable plugin separately, or you can remove one line in the bookmark.rb file to disable tags for bookmarks.

To get started download the plugin from its repository:

script/plugin install

The installation process will add several ruby files in the vendor/plugins directory. Create a new rails migration and cut and past the following self.up and self.down methods:

def self.up
  create_table :bookmarks, :force => true do |t|
    t.column :title, :string, :limit => 50, :default => ""
    t.column :created_at, :datetime, :null => false
    t.column :bookmarkable_type, :string,
      :limit => 15, :default => "", :null => false
    t.column :bookmarkable_id, :integer, :default => 0, :null => false
    t.column :user_id, :integer, :default => 0, :null => false

  add_index :bookmarks, ["user_id"], :name => "fk_bookmarks_user"

def self.down
  drop_table :bookmarks

Once you have the acts_as_bookmarkable plugin installed you can make your ActiveRecord classes act as models that can be bookmarkable by calling the acts_as_bookmakble method.

class Post < ActiveRecord::Base

In your controller you can bookmark a post with just a few lines of code:

post = Post.find(params[:id])
bmark = => someTitle)
post.bookmarks << bmark

And like my other plugins you can assign a bookmark to a user by using the user_id property. Here is an example of how to assign a bookmark to a user model.

bmark = => someTitle, :user_id => session[:user].id)

You have two options to retrieve the bookmarks for a given user. You can look up all the bookmarks for the given user that are of a certain bookmarkable type. Lets say I want to find all posts that have been bookmarked by the logged in user. To accomplish this I can do the following:

bmarks = Post.find_bookmarks_by_user(session[:user])

If you want all bookmarks for a given user, regardless of the type, then you can use the find_bookmarks_by_user method available from the Bookmark class.

bmarks = Bookmark.find_bookmarks_by_user(session[:user])

Technorati Tags: , , , , , ,

7 Responses to “Acts As Bookmarkable Plugin”

  • Frederico Araujo Says:

    “post.add_bookmark bmark” did not work,

    I had to do:

    “post.bookmarks << bmark”

  • Frederico Araujo Says:

    I have an add to your plugin. the below example is for finding all the Products bookmarked by a given user_id

    def self.find_bookmarked(user)
      bookmarks = Bookmark.find(:all,
        :conditions => ["bookmarkable_type = ? AND user_id = ?","Product",])
      products =
      for bookmark in bookmarks
        products << Product.find(bookmark.bookmarkable_id)
      return products
  • TechKnow Says:

    @Frederico – Thanks for you comment. I had removed the add_bookmark method sometime ago and must had forgotten to remove it from here.

    In regards to your second comment, I think I could add such a method as a convenience, but I don’t want to further confuse users with the existing find_bookmarks_by_user(user). You want an array of the bookmarked model such as Product or Post, and find_bookmarks_by_user returns an array of bookmarks. Did you know that a bookmark has a reference to your model? Yeah, you could say something like the following…

    product = bookmark.bookmarkable
  • Frederico Araujo Says:

    TechKnow, cool,
    thanks for the help.

  • Tom Says:

    I needed to do the following for Edge Rails in acts_as_bookmarkable.rb:

    has_many :bookmarks, :as => :bookmarkable, :dependent => true

    has_many :bookmarks, :as => :bookmarkable, :dependent => :destroy

    I did this to get my console to work.

  • TechKnow Says:

    @Tom – Thanks for the comment. I have update the plugin accordingly.

  • Donovan Says:

    This is really cool. Does the plug in work with Rails 2.0.x?

Leave a Reply