如何在 Rails 4.2 App 中按订阅计划类型设置 ActiveRecord 限制?

How To Set ActiveRecord Limits by Subscription Plan Type in Rails 4.2 App?

我有一个使用 Devise 进行身份验证的多租户 Rails 4.2 应用程序。我设置订阅计划如下:个人{每月和每年},企业{每月和每年}。个人计划限制为 5 个用户和 5 个计划。商业计划有无限的用户和计划。

我一直在尝试设置一种方法来阻止个人计划的用户在达到他们的限制时能够创建新的计划和用户记录。

我试过这个:in rails how to limit users post count saved in database before asking to upgrade their account

我的代码在 "plan" 模型中看起来像这样:

before_save :check_plan_quota
private

def check_plan_quota
if self.account.plans.count >= 5
  @quota_warning = "Plan limit reached."
  return false
 end
end

我的 "dashboard" 控制器中有这个(因为这是创建和列出计划的地方):

before_filter :check_quota
  private

 def check_quota
  if Plan.count >= 5
    @quota_warning = "Plan limit reached."
  end
end

我能够让它在用户达到 5 个计划后无法再添加任何记录的地方工作,并且也做到了 "add plan" 按钮基于@quota_warning 消失了.

          <p>
      <% if @quota_warning.present? %>
       <button type="button" class="btn btn-default"> You have <%= Plan.count %> Plans </button> &nbsp;&nbsp; - &nbsp;&nbsp; <button type="button" class="btn btn-secondary"> <%= @quota_warning %></button> 
       <% else %>
        <a href="/plans/new" class="btn btn-primary" data-toggle="modal" data-target="#styledModal">New Plan</a> &nbsp;&nbsp; - &nbsp;&nbsp; <button type="button" class="btn btn-default"> You have <%= Plan.count %> Plans </button>
        <% end %> 
      </p>

但是这将所有用户限制为只有 5 个计划,并且尽我所能尝试我无法获得一个 "if" 声明,该声明仅将此限制应用于个人月度或年度计划的用户。

然后我在 "user" 控制器上尝试了这个。

before_filter :check_user_limit, :only => :create

def check_user_limit
  redirect_to new_user_url if current_account.reached_user_limit?
end

在我输入的 "account" 模型中。

class Account < ActiveRecord::Base

has_many :users, dependent: :destroy, :inverse_of => :account
accepts_nested_attributes_for :users

has_one :admin, -> { where(admin: true) }, :class_name => "User"
accepts_nested_attributes_for :admin

:user_limit => Proc.new {|a| a.users.count }

has_many :plans, dependent: :destroy, :inverse_of => :account
accepts_nested_attributes_for :plans

:plan_limit => Proc.new {|a| a.plans.count }

user_limit 和 plan_limit 字段已添加到数据库的帐户列中,因此每个帐户都应在注册时设置这些限制。正如您可以想象的那样,一个人不能像那样使用上面的代码,但作为 rails 的新手,我不知道如何更好地使用它,甚至不知道它是否是最佳途径。

我尝试的第一种方法看起来很简单,但我无法使用类似

的方法
if account.user.plan.stripe_id = 'monthly' or 'yearly and Plan.count >= 5
@quota_warning = "Limit reached"
end

我的应用结构是这样的:

我需要关注的唯一限制是个人帐户,因为专业帐户没有限制。

似乎在模型中使用 user_limit 和 plan_limit 代码以及在控制器中创建的简单检查比另一个好一点,但我无法让它工作.我不确定我是否喜欢为此设置数据库字段。我明白 Proc.new 代码在做什么,但不知道我可以将它应用到什么地方。我尝试将它应用到 has_one :admin 的末尾,但出现以下错误:

Unknown key: :user_limit. Valid keys are: :class_name, :class, :foreign_key, :validate, :autosave, :dependent, :primary_key, :inverse_of, :required, :as, :foreign_type

我不确定这些信息是否足以帮助我,但如果我需要添加更多信息,请告诉我。

我会将其分解为一口大小的方法/逻辑块,然后在此基础上构建您想要的功能。大致如下:

INDIVIDUAL_USER_LIMIT = 5
INDIVIDUAL_PLAN_LIMIT = 5

def individual_plan?
  self.plan.type == :individual # or some such logic.
end

def over_user_limit?
  self.individual_plan? && self.users.count > INDIVIDUAL_USER_LIMIT
end

def over_plan_limit?
  self.individual_plan? && self.plans.count > INDIVIDUAL_PLANS_LIMIT
end

可能也值得你花时间好好看看实现一个 custom validator,它看起来像

class UserLimitValidator < ActiveModel::Validator
  def validate(account)
    if account.over_user_limit?
      account.errors[:users] << 'Too many users for your plan!'
    end
  end
end

并允许您验证您正在保存的模型是否具有预期的约束。

作为实现此功能时需要注意的一件事,请谨慎调用 self.plans.countself.users.count,因为它会进行额外的数据库查询,并可能导致一些严重的性能问题,例如作为 N+1 query problem.