-
Notifications
You must be signed in to change notification settings - Fork 118
Issue #3561 - Fix for bug "Discrepancy in Org Admin view of the #3564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| plans = @super_admin ? Plan.all : current_user.org.org_admin_plans | ||
| plans = plans.joins(:template, roles: [user: :org]).where(Role.creator_condition) | ||
| plans = plans.joins(:template, roles: [user: :org]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given these changes, it makes sense to remove the redundant .where(Role.creator_condition) when @super_admin evaluates to false.
But what about when @super_admin evaluates to true? The previous code applied .where(Role.creator_condition) for super admins, but now it does not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
I'm not 100% sure of that statement. Here is the app/models/plan.rb
# Deactivates the plan (sets all roles to inactive and visibility to :private)
#
# Returns Boolean
def deactivate!
# If no other :creator, :administrator or :editor is attached
# to the plan, then also deactivate all other active roles
# and set the plan's visibility to :private
if authors.empty?
roles.where(active: true).update_all(active: false)
self.visibility = Plan.visibilities[:privately_visible]
save!
else
false
end
endBased on this code, it seems that rather than just the creator role, ALL roles associated with the plan are set to Just to clarify, is this code change only menat to affect the CSV results? |
4ac02d2 to
65828ca
Compare
I have removed the clearly false comment in my commit. |
Organisation Plans and the related CSV Download".
Changes:
- where(Role.creator_condition) condition added to Plans retrieved in
the Org model's org_admin_plans method. This ensures that Plans
returned are only active plans.
- To avoid duplication we removed .where(Role.creator_condition) in
org_admin method in app/controllers/paginable/plans_controller.rb from
line
plans = plans.joins(:template, roles: [user::org]).where(Role.creator_condition).
- Updated RSpec tests for Org method org_admin_plans() in spec/models/org_spec.rb.
- Update CHANGELOG.
65828ca to
79d4571
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: Updated this comment for accuracy.
.where(roles: { active: true }).where(Role.creator_condition)irb(main):001> Role.creator_condition
=> "(\"roles\".\"access\" in (1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31))"So it is verifying that there is at least one active creator on the plan. As an edge case, there do in fact appear to be plans with a completely absent creator role. I believe the following SQL query can be used to check your db:
SELECT p.*
FROM plans p
WHERE NOT EXISTS (
SELECT 1
FROM roles r
WHERE r.plan_id = p.id
AND r.access IN (1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31)
);These plans mostly appear to be quite old in DMP Assistant's db. I can look further, but I assume these plans were created prior to the current bit field implementation in the Role model:
##
# Define Bit Field Values
# Column access
has_flags 1 => :creator, # 1
2 => :administrator, # 2
3 => :editor, # 4
4 => :commenter, # 8
5 => :reviewer, # 16
column: 'access',
check_for_column: !Rails.env.test?Are we sure we want to filter out plans with absent creator roles?
This PR code change aligns the CSV for the Org admin with the current Org admin plans view. Any further changes to will need to thought through. Do we want to do this here or address this in a separate issue? |
app/models/org.rb
Outdated
| .where(Role.creator_condition) | ||
| else | ||
| Plan.includes(:template, :phases, :roles, :users).where(id: combined_plan_ids) | ||
| .where.not(visibility: Plan.visibilities[:privately_visible]) | ||
| .where.not(visibility: Plan.visibilities[:is_test]) | ||
| .where(roles: { active: true }) | ||
| .where(Role.creator_condition) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if a refactor like the following would be a nice improvement:
def org_admin_plans
scope = Plan.includes(:template, :phases, :roles, :users)
.where(id: (native_plan_ids + affiliated_plan_ids).uniq)
.where(roles: { active: true })
.where(Role.creator_condition)
unless Rails.configuration.x.plans.org_admins_read_all
scope = scope.where.not(visibility: Plan.visibilities[:privately_visible])
.where.not(visibility: Plan.visibilities[:is_test])
end
scope
endThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for refactor advice. Nice and neat. Will add commit with change.
| plans = @super_admin ? Plan.all : current_user.org.org_admin_plans | ||
| plans = plans.joins(:template, roles: [user: :org]).where(Role.creator_condition) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about the following for a refactor?
plans = @super_admin ? Plan.where(Role.creator_condition) : current_user.org.org_admin_plans
plans = plans.joins(:template, roles: [user: :org])There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code change in a new commit with another bit of re-factored code cited above.
spec/models/org_spec.rb
Outdated
| context 'when user belongs to Org and a plan removed by creator, but cowner still active.' do | ||
| before do | ||
| plan.add_user!(user.id, :administrator) | ||
| Rails.configuration.x.plans.org_admins_read_all = true | ||
| coowner = create(:user, org: org1) | ||
| org1plan4.add_user!(coowner.id, :coowner) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're trying to add a :coowner here, but it looks like a :commenter is being added instead:
# Creates a role for the specified user (will update the user's
# existing role if it already exists)
#
# Expects a User.id and access_type from the following list:
# :creator, :administrator, :editor, :commenter
#
# Returns Boolean
def add_user!(user_id, access_type = :commenter)
user = User.where(id: user_id).first
if user.present?
role = Role.find_or_initialize_by(user_id: user_id, plan_id: id)
# Access is cumulative, so set the appropriate flags
# (e.g. an administrator can also edit and comment)
case access_type
when :creator
role.creator = true
role.administrator = true
role.editor = true
when :administrator
role.administrator = true
role.editor = true
when :editor
role.editor = true
end
role.commenter = true
role.save
else
false
end
end 386: org1plan4.roles.map { |r| r.update(active: false) if r.user_id == owner_id }
387: byebug
=> 388: end
389:
390: it { is_expected.to include(org1plan1, org1plan2, org1plan3) }
391: it { is_expected.not_to include(org1plan4) }
392: end
(byebug) roles = org1plan4.roles
#<ActiveRecord::Associations::CollectionProxy [#<Role id: 4, user_id: 4, plan_id: 7, created_at: "2025-12-03 17:37:57.852288000 +0000", updated_at: "2025-12-03 17:37:57.855932000 +0000", access: 15, active: false>, #<Role id: 6, user_id: 6, plan_id: 7, created_at: "2025-12-03 17:37:57.987364000 +0000", updated_at: "2025-12-03 17:37:57.987364000 +0000", access: 8, active: true>]>
(byebug) roles.last.creator?
false
(byebug) roles.last.administrator?
false
(byebug) roles.last.editor?
false
(byebug) roles.last.commenter?
true
(byebug) roles.last.reviewer?
false
(byebug)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad. Only allowed access_types ":creator, :administrator, :editor, :commenter". Will update code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated tests to only add access_type :administrator for a coowner test.
Changes: - Refactored Org model org_admin_plans() method. - Refactored Paginable Plans controller method org_admin().
coowner being used incorrectly as an Role access_type. A coowner is any user apart from the plan creator with the Role administrator.
f84ad69 to
fc48b6c
Compare
Sorry, I've updated that previous comment I made, as it was partly inaccurate. (However, there are in fact active plans with non-existent creator roles.) I am thinking of an alternate way to align the CSV with the Org Admin plans. This PR currently does so by applying |
I tried digging back into the |
Let us research the history of the code evolution to answer this intelligently. However, we in DMPOnline focused on aligning what the Org admins saw in the UI with the CSV download for this PR. I suspect we need a new issue for further changes. |
I guess the two will be aligned whether we add or remove Maybe an example scenario like the following would help: Suppose Marta is the org_admin, and John and I belong to her org. I create a plan, mark it organisationally visible, and add John as a co-owner. Marta can see this plan. Later I delete myself from the plan, leaving John as an active co-owner but with no remaining active “creator” role on the record. Should Marta still see it in the Org Admin plans page and CSV? I don't know if this PR provides any further insights. It made a change that replaced |
This PR as I have said was to address the discrepancy between view and CSV because the CSV was using a different call. This just aligned the call. The users were finding it strange that the CSV had extra plans not visible in UI. |
Sounds good. Sorry, yes, my review/questions might be a bit overkill. This only changes/reduces the CSV results to align with the org admin view. |

Under the current code an Org plan that is removed by owner or coowner will be visible by the Org admins for the Org in the CSV. The Org Admin, correctly, does not show plan. With this change in code the removed plan is no longer present in the CSV.
To test:
Look at a given removed plan before and after code change.