Limit By Scope Rails Plugin
I’m pleased to announce the release of the LimitByScope plugin, the second package in the Software as a Service project.
From the README:
This plugin adds class limit, available, and capacity methods to enforce quota limits on the creation of models. The plugin is primarily for use with the acts_as_scoped plugin (part of the saas project) because it otherwise enforces a flat limit on the creation of limited models. If used with the acts_as_scoped plugin you can lock users to a scope such as host or domain then ensure they can only create the number object within their plan. The Usage section below should explain a little better.
Documentation
http://saas.rubyforge.org/limit_by_scope
Rubyforge Project
http://rubyforge.org/projects/saas
Usage
# plan attributes:
# - name
# - price
# - item_limit
class Plan < ActiveRecord::Base
has_many :hosts
end
# host attributes:
# - name
# - plan_id
class Host < ActiveRecord::Base
cattr_accessor :current
belongs_to :plan
end
# item attributes
# - name
# - host_id
class Item < ActiveRecord::Base
limit_by_scope :host, :delegate => :plan, :error => 'Quota met: #{self.class.limit}, please upgrade your plan to add more.'
belongs_to :host
end
# for best results, use with acts_as_scoped like so:
class Item < ActiveRecord::Base
acts_as_scoped :host
limit_by_scope :host, :delegate => :plan, :error => 'Your service tier only allows #{self.class.limit}, please <a href=\"/upgrade?id=#{self.host.id}\">upgrade</a> your plan to add more.'
belongs_to :host
end
class ApplicationController < ActionController::Base
...
before_filter :current_host
def current_host
Host.current = Host.find_by_name(request.subdomains.first)
redirect_to('/not_found.html') and return false if Host.current.nil?
end
...
Installation
script/plugin install svn://rubyforge.org/var/svn/saas/limit_by_scope/trunk/limit_by_scope
Software as a Service
The plugin is part of the Software as a Service project on Rubyforge. You can use this plugin in conjunction with something similar to the userstamp plugin to automagically limit the scope of your find, calculate, save, delete methods. It is used with other plugins as a drop in that will allow you to turn just about any rails application into a software as a service.
Rails Scoping Plugin
A few days ago I posted about auto scoping in Rails. My implementation was pretty basic, and was only really good for my app. One of the things I really love about Rails is the amount of plugins available, and the communities willingness to share them. This is really great because I came across the maxed out scope plugin today at Agile Web Development and I’m impressed. Life is good.
Problems with UserEngine & LoginEngine and Rails 1.2
So I’ve been looking to add some of the new REST functionality to an app I’ve been working on based in Rails 1.1.1 code. What better way then to use the updated functionality found in Rails 1.2. Well the problem is that fact that a long time ago I decided that Engines were a good idea. They provided functionality that was pretty easy to override and was pretty much self contained. That’s what made them a good fit then.
The problem now is that when engines go unsupported like how UserEngine and LoginEngine have with Engines 1.2, it makes it difficult to upgrade Rails. I made the attempt and found out the hard way that ‘config’ which available in previous versions of Engines is no longer available, and the suggested workaround is to use mattr_accessor. This is problematic because if you do that you are essentially making available every configuration option as an actionable method in your controller. The issue here is in the way UserEngine syncs permissions.
The result, every configuration option has a permission object and some actual actionable methods don’t end up with permission objects. Unfortunately I don’t have the solution here, but it seems that the only reason UserEngine and LoginEngine don’t continue to work is because Engines 1.2 dropped some functionality, and it doesn’t really seem due to the fact that either of those engines have offending code…afaik the whole reason to update to Engines 1.2 is because the previous version breaks routing in Rails 1.2.
In retrospect generators seem a billion times better than engines because in this case relying on engines to keep some minimum level of backward compatibility was a big mistake.
For now I have to try to convert these two engines. I’ll repost as I make progress. Someone through me a line.
Long live acts_as_authenticated.
