#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