Inkwell
Inkwell provides a simple way to add social networking features (e.g., comments, reblogs, favorites, following/followers, communities and timelines) to your Ruby on Rails application.
Installation
To get Inkwell from RubyGems, put the following line in the Gemfile.
gem 'inkwell'Alternatively, you can get it from Github (This version may contain unfinished features).
gem 'inkwell', :git => 'git://github.com/salkar/inkwell.git'After that, run bundle install
Next, get gem migrations:
$ rake inkwell:install:migrationsand rake db:migrate them.
Upgrading
After upgrading Inkwell remember to get new migrations and migrate them.
$ rake inkwell:install:migrations
$ rake db:migrateUsage
Favoriting features
Setup
Include relevant modules to models:
- add
include Inkwell::CanFavoriteto models which instances should be able to favorite other objects - add
include Inkwell::CanBeFavoritedto models which instances should be able to be added to favorites
For sample:
# app/models/user.rb
class User < ApplicationRecord
include Inkwell::CanFavorite
#...
end
# app/models/post.rb
class Post < ApplicationRecord
include Inkwell::CanBeFavorited
#...
endInkwell::CanFavorite usage
user.favorite(post)After that post will appear in the user.favorites. Also if user
sees post in someone else's timelines (or blog, favorites, etc.),
post will have favorited_in_timeline attribute with true value.
user.unfavorite(post)Rolls back favorite effects.
user.favorite?(post)
#=> false
user.favorite(post)
#=> true
user.favorite?(post)
#=> trueCheck that post is added to favorites by user.
Notice: if obj passed to favorite, unfavorite or favorite? does not
include Inkwell::CanBeFavorited Inkwell::Errors::NotFavoritable will
be raised
Return array of instances favorited by object.
user.favorites
#=> [#<Post>, #<Comment>, ...]If favorites used without block, all favorited objects will be
returned (without pagination, ordering, etc). In this case Array is
returned not Relation!
For perform operations on relation block should be used:
# Gemfile
gem 'kaminari'
# code
user.favorites do |relation|
relation.page(1).order('created_at DESC')
end
#=> [#<Post>, #<Comment>, ...]Notice: relation is relation of Inkwell::Favorite instances (internal
Inkwell model)
Notice: realization with block looks complicated, but it helps with solve troubles with many-to-many relations through other polymorphic relations on both sides.
If there is necessary to get each result's object with flags for another
user (favorited_in_timeline, reblogged_in_timeline, etc.),
for_viewer should be passed:
user.favorite(post)
user.favorite(other_post)
other_user.favorite(other_post)
result = user.favorites(for_viewer: other_user)
result.detect{|item| item == post}.favorited_in_timeline
#=> false
result.detect{|item| item == other_post}.favorited_in_timeline
#=> truepost.favorited_by.each do |obj|
obj.favorites_count
endUse favorites_count (instead of obj.favorites.count or
obj.inkwell_favorited.count for sample) for prevent n+1 because
favorites_count get counter from inkwell cache included in favorited_by
by default.
Inkwell::CanBeFavorited usage
post.favorited_by?(user)
#=> false
user.favorite(post)
#=> true
post.favorited_by?(user)
#=> trueCheck that post is added to favorites by user.
Notice: if subject does not include Inkwell::CanFavorite
Inkwell::Errors::CannotFavorite will be raised
user.favorites.each do |obj|
obj.favorited_count
endUse favorited_count (instead of obj.favorited_by.count or
obj.inkwell_favorited.count for sample) for prevent n+1 because
favorites_count get counter from inkwell cache included in favorites
by default.
Return array of instances who favorite this object.
post.favorited_by
#=> [#<User>, #<Community>, ...] # Array, NOT Relation# Gemfile
gem 'kaminari'
# code
user.favorited_by do |relation|
# relation - Inkwell::Favorite relation
relation.page(1).order('created_at DESC')
end
#=> [#<User>, #<Community>, ...] # Array, NOT RelationNotice: for more details see Inkwell::CanFavorite#favorites . It works the same way.
Blogging features
Setup
Include relevant modules to models:
- add
include Inkwell::CanBloggingto models which instances should be able to add objects to their blog. - add
include Inkwell::CanBeBloggedto models which instances should be able to be added to blogs.
For sample:
# app/models/user.rb
class User < ApplicationRecord
include Inkwell::CanBlogging
#...
end
# app/models/post.rb
class Post < ApplicationRecord
include Inkwell::CanBeBlogged
#...
endTo automatically add posts to user blog, you can do the following:
class Post < ApplicationRecord
include Inkwell::CanBeBlogged
#...
belongs_to :user
#...
validates :user, presence: true
#...
after_create :blog_filling
#...
private
def blog_filling
user.add_to_blog(self)
end
end
Inkwell::CanBlogging usage
user.add_to_blog(post)After that post will appear in the user.blog.
user.remove_from_blog(post)Rolls back add_to_blog effects.
user.added_to_blog?(post)
#=> false
user.add_to_blog(post)
#=> true
user.added_to_blog?(post)
#=> trueCheck that post is added to user's blog.
Notice: if obj passed to add_to_blog, remove_from_blog or
added_to_blog? does not include Inkwell::CanBeBlogged
Inkwell::Errors::NotBloggable will be raised
Return array of instances blogged and reblogged by object.
user.blogs
#=> [#<Post>, #<Comment>, ...] # array NOT relation# Gemfile
gem 'kaminari'
# code
user.blogs do |relation|
# relation - Inkwell::BlogItem relation
relation.page(1).order('created_at DESC')
end
#=> [#<Post>, #<Comment>, ...]Reblogged items has reblog_in_timeline flag
user.add_to_blog(post)
user.reblog(other_post)
result = user.blogs
result.detect{|item| item == post}.reblog_in_timeline
#=> false
result.detect{|item| item == other_post}.reblog_in_timeline
#=> trueIf there is necessary to get each result's object with flags for another
user (reblogged_in_timeline, favorited_in_timeline, etc.),
for_viewer should be passed:
user.add_to_blog(post)
user.add_to_blog(other_post)
other_user.reblog(other_post)
result = user.blog(for_viewer: other_user)
result.detect{|item| item == post}.reblogged_in_timeline
#=> false
result.detect{|item| item == other_post}.reblogged_in_timeline
#=> trueNotice: for more details see Inkwell::CanFavorite#favorites . It works the same way.
Return added to blog objects count (including reblogs).
user.blog_items_countUse blog_items_count for prevent n+1.
Inkwell::CanBeBlogged usage
post.blogged_by?(user)
#=> false
user.add_to_blog(post)
#=> true
post.blogged_by?(user)
#=> trueCheck that post is added to user's blog.
Notice: if subject does not include Inkwell::CanBlogging
Inkwell::Errors::CannotBlogging will be raised
Return instance who add to blog this object (owner of this object).
user.add_to_blog(post)
post.blogged_by
#=> #<User> # userReblog features
Setup
Include relevant modules to models:
- add
include Inkwell::CanReblogto models which instances should be able to reblog objects. If object is reblogged, it is added to subject's blog. - add
include Inkwell::CanBeRebloggedto models which instances should be able to be reblogged.
For sample:
# app/models/user.rb
class User < ApplicationRecord
include Inkwell::CanBlogging
include Inkwell::CanReblog
#...
end
# app/models/post.rb
class Post < ApplicationRecord
include Inkwell::CanBeBlogged
include Inkwell::CanBeReblogged
#...
endInkwell::CanReblog usage
user.reblog(post)After that post will appear in the user.blog as reblog (reblog_in_timeline flag).
user.unreblog(post)Rolls back reblog effects.
user.reblog?(post)
#=> false
user.reblog(post)
#=> true
user.reblog?(post)
#=> trueCheck that post is reblogged by user and added to user's blog.
Notice: if obj passed to reblog, unreblog or
reblog? does not include Inkwell::CanBeReblogged
Inkwell::Errors::NotRebloggable will be raised
Return reblogged objects count.
user.reblogs_countUse reblogs_count instead of obj.reblogs.count or
obj.inkwell_reblogs.count for sample for prevent n+1.
Inkwell::CanBeReblogged usage
post.reblogged_by?(user)
#=> false
user.reblog(post)
#=> true
post.reblogged_by?(user)
#=> trueCheck that post is added to users's blog as reblog.
Notice: if subject does not include Inkwell::CanReblog
Inkwell::Errors::CannotReblog will be raised
user.blog.each do |obj|
obj.try(:reblogged_count) # try is not needed if all objects in blog are rebloggable
endUse reblogged_count for prevent n+1.
Return array of instances who reblog this object.
post.reblogged_by
#=> [#<User>, #<Community>, ...] # Array, NOT Relation# Gemfile
gem 'kaminari'
# code
user.reblogged_by do |relation|
# relation - Inkwell::BlogItem relation
relation.page(1).order('created_at DESC')
end
#=> [#<User>, #<Community>, ...] # Array, NOT RelationNotice: for more details see Inkwell::CanFavorite#favorites . It works the same way.