このコードを実行すると、次のメソッドからできるだけ多くのifステートメントを削除する必要があります。
# returns permissions if user is set in security context
def get_user_permissions
user_permissions = Set.new
if (@user != nil)
user_permissions << :DEFAULT_PERMISSION
if (has_cm_team_role)
user_permissions << :CM_TEAM_ROLE_PERMISSION
end
if (has_cm_invoice_view_role || has_invoice_finance_role)
user_permissions << :CM_INVOICE_USER_PERMISSION
user_permissions << :INVOICE_VIEW_PERMISSION
user_permissions << :ACCESS_ALL_INVOICE_PERMISSION
end
if (has_invoice_finance_role)
user_permissions << :FINANCE_INVOICE_PERMISSION
end
if (has_application_access)
user_permissions << :CM_INVOICE_USER_PERMISSION
end
if (has_application_access(:CM_INVOICE_ROLE))
user_permissions << :CM_ANY_INVOICE_PERMISSION
end
if (has_application_access(:PA_INVOICE_ROLE))
user_permissions << :PA_ANY_INVOICE_PERMISSION
end
if (has_application_access(:SDT_INVOICE_ROLE))
user_permissions << :SDT_ANY_INVOICE_PERMISSION
end
end
user_permissions
end
私の最初の試みはほとんど機能しますが、いくつかのテストは失敗します。
def get_user_permissions
user_permissions = Set.new
if (@user != nil)
user_permissions << :DEFAULT_PERMISSION
# add the permissions in another method
add_permissions(user_permissions)
end
user_permissions
end
def add_permissions(user_permissions)
# a hash where each key is a condition, and each value is a permission
hash = {
has_cm_team_role => :CM_TEAM_ROLE_PERMISSION,
has_cm_invoice_view_role || has_invoice_finance_role => :CM_INVOICE_USER_PERMISSION,
has_cm_invoice_view_role || has_invoice_finance_role => :INVOICE_VIEW_PERMISSION,
has_cm_invoice_view_role || has_invoice_finance_role => :ACCESS_ALL_INVOICE_PERMISSION,
has_invoice_finance_role => :FINANCE_INVOICE_PERMISSION,
has_application_access => :CM_INVOICE_USER_PERMISSION,
has_application_access(:CM_INVOICE_ROLE) => :CM_ANY_INVOICE_PERMISSION,
has_application_access(:PA_INVOICE_ROLE) => :PA_ANY_INVOICE_PERMISSION,
has_application_access(:SDT_INVOICE_ROLE) => :SDT_ANY_INVOICE_PERMISSION
}
# loop through the hash and add permissions if the key is true
hash.each do |condition, permission|
if (condition)
user_permissions << permission
end
end
このアプローチの問題は、3つのORステートメント(ハッシュの2番目、3番目、4番目のキー)がそれぞれによって評価されないことです。だから私は次のようにProcsを使用してこれを修正します:
def add_permissions(user_permissions)
hash = {
Proc.new{has_cm_team_role} => :CM_TEAM_ROLE_PERMISSION,
Proc.new{has_cm_invoice_view_role || has_invoice_finance_role} => :CM_INVOICE_USER_PERMISSION,
Proc.new{has_cm_invoice_view_role || has_invoice_finance_role} => :INVOICE_VIEW_PERMISSION,
Proc.new{has_cm_invoice_view_role || has_invoice_finance_role} => :ACCESS_ALL_INVOICE_PERMISSION,
Proc.new{has_invoice_finance_role} => :FINANCE_INVOICE_PERMISSION,
Proc.new{has_application_access} => :CM_INVOICE_USER_PERMISSION,
Proc.new{has_application_access(:CM_INVOICE_ROLE)} => :CM_ANY_INVOICE_PERMISSION,
Proc.new{has_application_access(:PA_INVOICE_ROLE)} => :PA_ANY_INVOICE_PERMISSION,
Proc.new{has_application_access(:SDT_INVOICE_ROLE)} => :SDT_ANY_INVOICE_PERMISSION
}
hash.each do |condition, permission|
if (condition.call)
user_permissions << permission
end
end
end
OK、これは機能し、テストはすべて合格ですが、3つが正しく評価されるように、すべてのキーをProcsに変換しています。Procsは、必要な場合、つまり2番目、3番目、4番目のキーにのみ使用したいと思います。
def add_permissions(user_permissions)
hash = {
# just use the method name unless a Proc is required
has_cm_team_role => :CM_TEAM_ROLE_PERMISSION,
# use a Proc here, so that the OR is evaluated later
Proc.new{has_cm_invoice_view_role || has_invoice_finance_role} => :CM_INVOICE_USER_PERMISSION,
Proc.new{has_cm_invoice_view_role || has_invoice_finance_role} => :INVOICE_VIEW_PERMISSION,
Proc.new{has_cm_invoice_view_role || has_invoice_finance_role} => :ACCESS_ALL_INVOICE_PERMISSION,
has_invoice_finance_role => :FINANCE_INVOICE_PERMISSION,
has_application_access => :CM_INVOICE_USER_PERMISSION,
has_application_access(:CM_INVOICE_ROLE) => :CM_ANY_INVOICE_PERMISSION,
has_application_access(:PA_INVOICE_ROLE) => :PA_ANY_INVOICE_PERMISSION,
has_application_access(:SDT_INVOICE_ROLE) => :SDT_ANY_INVOICE_PERMISSION
}
次に、キーがProcであるかどうかを判断するためのある種のメソッドで、そうである場合はそれを呼び出しますが、そうでない場合は、条件を他のキーと同じように扱います。
hash.each do |condition, permission|
if condition.is_proc?
if (condition.call)
user_permissions << permission
end
elsif condition
user_permissions << permission
end
end
end
任意のヒント?私がこれをやろうとした方法よりも良いアイデアはありますか?これを行うことで、より周期的に複雑にしましたか?すべてのキーがProcsである作業ソリューションに固執する必要がありますか?