Reputation: 1351
So I am building out an application using Rails 4 and the Apartment Gem.
I am fairly new to multitenancy and have come to the point where I am building out user plans.
I have 4 main plans and I want each plan to limit the number of users that can be created, before telling the account owner or admin that they need to upgrade to register new users.
I think I am more stuck on where this should be done.. In my account model I have my constant for Plan:
PLAN = %w[responder first_responder patrol_pro guardian]
each of these plan_types
(column I am saving to on sign up) have a set number of users that can be created, these are also set as constants below:
RESPONDER_PLAN_USER_LIMIT = 6
FIRST_RESPONDER_PLAN_USER_LIMIT = 12
PATROL_PRO_PLAN_USER_LIMIT = 30
GUARDIAN_PLAN_USER_LIMIT = 60
I have also created the below methods to verify the plan type however this seems clunky and was wondering if there was a way i could do this in one method instead of 4
def responder_plan?
self.plan_type == 'responder'
end
def first_responder_plan?
self.plan_type == 'first_responder'
end
def patrol_pro_plan?
self.plan_type == 'patrol_pro'
end
def guardian_plan?
self.plan_type == 'guardian'
end
Now for the last issue, to actually count the users attached to the account I was planning on using a Validator to do so, i am just un-sure of how to create the model method.
I was thinking something like this:
def over_user_limit?
self.individual_plan? && self.users.count > INDIVIDUAL_USER_LIMIT
end
but I am stuck on how to do this with multiple user types?
Any assistance here would be greatly appreciated.
EDIT 1 : Error Message when trying to add the enum to my form
SyntaxError at /accounts/new
syntax error, unexpected tIDENTIFIER, expecting ')'
first_responder: 12
^
/Users/developer/Desktop/PatrolVault-Saas/PV_SAAS/app/models/plan.rb:7: syntax error, unexpected ':', expecting keyword_end
patrol_pro: 30
^
/Users/developer/Desktop/PatrolVault-Saas/PV_SAAS/app/models/plan.rb:8: syntax error, unexpected ':', expecting keyword_end
guardian: 60
^
and for brevity, here is my form field for it:
<%= f.fields_for :plan do |plan| %>
<div class="col-xs-12">
<%= f.select :plan_type, options_for_select(Plan.plan_types.map {|k, v| [k.humanize.capitalize, k]}) %>
</div>
<% end %>
EDIT # 2 Remaining Error Message Referencing the Enum
Here is my Plan Model:
enum :plan_type, [:responder, :first_responder, :patrol_pro, :guardian]
USER_LIMITS = ActiveSupport::HashWithIndifferentAccess.new( responder: 6, first_responder: 12, patrol_pro: 30, guardian: 60 )
Here is the Error Message:
And the form item has not changed.
Upvotes: 0
Views: 53
Reputation: 102026
The main issue is that the distribution of responsibilities is very muddled.
I would start by setting up two models with very clear responsibilities:
class Account < ActiveRecord::Base
belongs_to :company
has_one :plan
end
class Plan < ActiveRecord::Base
belongs_to :account
end
The logic of defining the rules for different types of plans is definitely not the Account models job.
So lets implement the rules in the Plan class:
class Plan < ActiveRecord::Base
belongs_to :account
# declare the column plans.plan_type as integer.
enum plan_type: [:responder, :first_responder, :patrol_pro, :guardian]
USER_LIMITS = ActiveSupport::HashWithIndifferentAccess.new(
responder: 6,
first_responder: 12,
patrol_pro: 30,
guardian: 60
)
def user_limit
USER_LIMITS[self.plan_type]
end
end
You can then implement a validation:
class Plan < ActiveRecord::Base
belongs_to :account
# declare the column plans.plan_type as integer.
enum plan_type: [:responder, :first_responder, :patrol_pro, :guardian]
USER_LIMITS = ActiveSupport::HashWithIndifferentAccess.new(
responder: 6,
first_responder: 12,
patrol_pro: 30,
guardian: 60
)
validates :must_be_below_user_limit
def user_limit
USER_LIMITS[self.plan_type]
end
def must_be_below_user_limit
if self.account.users.size >= user_limit
errors[:user_limit] = "can not more than #{user_limit} users"
end
end
end
Upvotes: 1