Я постараюсь объяснить это очень просто. Итак, я пропустил любой код, который не нужен для иллюстрации проблемы.
Давайте предположим модель:
class Model < ActiveRecord::Base
# Join class storing grants for users, e.g. 'admin', 'default'
has_many :user_grants
# Grant a user a certain grant
def grant_user(user, grant)
self.user_grants.build(:user => user, :grant => grant)
end
# Some action is done by a user, but ensure user has required grants
def action(user, action_type)
unless user_grants.find_by_user_id_and_grant(user, GrantEnum::ADMIN)
raise ModelUserNotAllowedError.new
end
...action code...
end
Я пропустил код для пользователя и некоторых других моделей, потому что они не имеют отношения к иллюстрации ...
Мы создаем экземпляр кода:
1: @model = Model.new
2: @user = User.new
3: @model.grant_user(@user, GrantEnum::ADMIN)
4: @model.action(@user, ActionEnum::SOMETHING)
Строка 4. вызовет ModelUserNotAllowedError, поскольку требуемая сборка гранта в строке 3 в настоящее время не сохраняется, но методы поиска работают только с постоянными данными. С логической точки зрения, ошибка не должна возникать, потому что пользователю предоставлены права.
Я использую self.user_grants.build , поскольку модель может не сохраняться при вызове grant_user.
Итак, какие есть варианты, чтобы заставить это работать:
1.) Внедрите код, который использует только association.create вместо association.build , чтобы обеспечить актуальность методов поиска. Это также требует, чтобы сначала спасти родителей.
2.) Внедрите код, который проверяет как постоянные данные, используя методы поиска , так и непостоянные данные, просматривая привязку, например, учитывая приведенный выше пример, можно проверить непостоянные данные:
user_grants.each do |user_grant|
if user_grant.grant.eql?(GrantEnum::ADMIN)
return true
end
end
Однако предложение № 2 кажется плохой идеей. Итак, давайте забудем об этом ...
Есть ли другие варианты? например Есть ли способ получить методы поиска для проверки непостоянных данных? Надеюсь получить новые идеи ...