Проверка для must_be_below_user_limit, позволяющая пользователям превышать пользовательский лимит Rails 4

#ruby-on-rails #validation #ruby-on-rails-4

#ruby-на-рельсах #валидация #ruby-on-rails-4

Вопрос:

Итак, я создаю многопользовательское приложение в Rails 4 с помощью Apartment, Devise и Devise_Invitable.

Я хочу ограничить количество пользователей в каждой учетной записи в зависимости от типа плана.

Когда я создаю пользователя, проверка должна быть направлена на то, чтобы убедиться, что количество пользователей ниже предела плана и равно ли оно пределу плана:

А) Не разрешить создание пользователя Б) показать флэш-сообщение, в котором владельцу / администратору сообщается, что им необходимо обновить свою учетную запись.

В настоящее время проверка не выдает ошибку при создании, но также не препятствует созданию пользователя.

Вот Пользовательская модель:

 class User < ApplicationRecord
  # Constants amp; Enums
  USER_LIMITS = ActiveSupport::HashWithIndifferentAccess.new(
    #Plan Name      #Auth Users
    responder:        6,
    first_responder:  12,
    patrol_pro:       30,
    guardian:         60
  )

  # Before Actions

  # Devise Modules
  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :invitable, :lockable, :timeoutable

  # Relationships
  belongs_to :account, optional: true

  # Validations
  validates :f_name, presence: true
  validates :l_name, presence: true
  validates :date_of_birth, presence: true

  validate :must_be_below_user_limit, on: [:create]

  # Custom Methods
  def full_name
    l_name.upcase   ", "   f_name
  end

  def user_limit
    USER_LIMITS[account.plan.plan_type]
  end

  def must_be_below_user_limit
    if account.present? amp;amp; persisted? amp;amp; account.users.size > user_limit
     errors[:user_limit] = "can not have more than #{user_limit} users"
    end
  end

end
  

Вот модель плана:

 class Plan < ApplicationRecord
  # Enum amp; Constants
  enum plan_type: [:responder, :first_responder, :patrol_pro, :guardian]

  USER_LIMITS = ActiveSupport::HashWithIndifferentAccess.new(
    #Plan Name      #Auth Users
    responder:        6,
    first_responder:  12,
    patrol_pro:       30,
    guardian:         60
  )

  # Before Actions

  # Relationships
  belongs_to :account, optional: true

  # Validations

end
  

и вот модель учетной записи:

 class Account < ApplicationRecord
  include ImageUploader[:image]
  # Constants
  RESTRICTED_SUBDOMAINS = %w(www patrolvault admin test type taurenapplabs taurenmaterialservices)

  # Before Actions
  before_validation :downcase_subdomain

  # Relationships
  belongs_to :owner, class_name: 'User', optional: true
  accepts_nested_attributes_for :owner
  has_many :users

  # Validations
  validates :owner, presence: true

  validates :subdomain, presence: true,
                        uniqueness: { case_sensitive: false },
                        format: { with: /A[w-] Z/i, message: 'Contains invalid characters.' },
                        exclusion: { in: RESTRICTED_SUBDOMAINS, message: 'Restricted domain name'}

  has_one :plan
  accepts_nested_attributes_for :plan

  private

  def downcase_subdomain
    self.subdomain = self.subdomain.downcase
  end

end
  

Как я уже сказал, дело не в том, что проверка завершается с ошибкой .. но это также не мешает созданию пользователя. Любая помощь здесь была бы очень признательна.

Комментарии:

1. account.users.size это будет верно только в том случае, если последний пользователь уже был создан… так вот в чем ошибка. Вы могли бы попробовать >= вместо того, чтобы просто > . Я бы также подумал о добавлении before_save в User модель, которая вообще не позволяет пользователю сохраняться, если достигнут предел.

2. @TarynEast итак, должен ли я изменить проверки на before_save? или также добавьте перед сохранением, чтобы вызвать :must_be_below_user_limit также? и мыслительный процесс на > состоял в том, чтобы не разрешить создание пользователя, если количество было равно user_limit .

3. Как вы сохраняете модели плана? (создавать, сохранять и т.д.)

4. план создается через учетную запись, это просто выпадающее окно выбора с именем плана в нем я думаю, что проверки должны выполняться в модели пользователей и просто ссылаться на название плана

5. «или также добавьте перед сохранением для вызова :must_be_below_user_limit» На этом этапе я бы добавил его и посмотрел, поможет ли это. «и мыслительный процесс на > заключался в том, чтобы не разрешать создание пользователя, если количество было равно user_limit.» да, но это не то, что на самом деле происходит… это разрешено до тех пор, пока количество пользователей не станет больше предела … и вы хотите, чтобы проверка завершилась неудачей, если количество пользователей равно (или больше) пределу…

Ответ №1:

Попробуйте добавить retrun false в must_be_below_user_limit методе.

 def must_be_below_user_limit
  if account.present? amp;amp; persisted? amp;amp; account.users.count > user_limit
    errors[:user_limit] = "can not have more than #{user_limit} users"
    return false
  end
end