Make subscription plans and enforce their limits with Planify.
Requirements
Ruby:
- 1.9.3
- 2.0.0
- JRuby (1.9 mode)
- Rubinius (1.9 mode)
Mongoid 3 (Support for other ORMs will be a future improvement)
Installation
Add this line to your application's Gemfile:
gem 'planify'
And then execute:
$ bundle
Or install it yourself as:
$ gem install planify
Setup
Limitables
Limitables are classes which can be limited based on plan settings. To create a limitable, include the Planify::Limitable
mixin in your class.
# app/models/widget.rb
class Widget
include Mongoid::Document
include Planify::Limitable
...
end
Plans
Plans hold information about how many instances of a Limitable
can be created, as well as which features are available to users subscribed to this plan:
# config/initializers/plans.rb
Planify::Plans.define :starter do
price 5.00 # Costs 5 dollars
description "The perfect plan to get you started"
max Widget, 100 # Can only create up to 100 widgets before needing to upgrade
feature :ajax_search # This plan supports ajax search
enable_feature :live_reload # And live reloading
disable_feature :guest_account # But no guest accounts
feature :support_tickets, false # And no support tickets
end
Users
Add the Planify::User
mixin to your user class. This will keep track of how many limitables the user has created, as well as their plan and plan overrides:
class User
include Mongoid::Document
include Planify::User
...
end
Then assign the user a plan:
@user = User.create
@user.has_plan :starter
You can also assign user-specific overrides to plan limits and features:
# This user has half the widgets and no ajax-search
@user.has_plan :starter do
max Widget, 50
disable_feature :ajax_search
end
Usage
After creating your Limitables, Plans, and User, you are ready to start enforcing limits.
# widgets_controller.rb
def create
@user = current_user
if @user.can_create? Widget # User has not hit their Widget cap
@widget = Widget.create(params[:widget])
@user.created :widget
end
end
def destroy
@user = current_user
@widget = Widget.find(params[:id])
@widget.destroy
@user.destroyed @widget
end
You can also test for features:
# _nav.haml
-if current_user.has_feature? :ajax_search
=ajax_search_form
Rails Integration
When used inside a Rails project, Planify automatically adds two methods to your controllers: enforce_limit!
and limit_exceeded!
. enforce_limit!
will call limit_exceeded!
if the user is over their limit.
# app/controllers/widget_controller.rb
class WidgetController < ApplicationController
before_filter :enforce_widget_limit, only: [:new, :create]
...
private
def enforce_widget_limit
# If the user's Widget limit is exceeded, limit_exceeded! will be called
enforce_limit! current_user, Widget
end
end
The default behavior of limit_exceeded!
is to raise an Exception. You can change this behavior by creating your own limit_exceeded!
method in your ApplicationController
.
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def limit_exceeded!
redirect_to upgrade_plan_url, notice: "You must upgrade your account!"
end
end
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Add some specs (so I don't accidentally break your feature in the future)
- Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request