CSC/ECE 517 Spring 2025 - E2516. Reimplement teams users controller.rb
E2516: Reimplement teams_users_controller.rb
Overview
Our goal for this project is to reimplement the TeamUsersController and change it to TeamsParticipantsController thereby strictly following DRY and SOLID principles. Presently, the TeamsUsersController is responsible for managing the interactions between teams and participants. Teams are associated with assignments and courses while participants are associated with these.
As of now, the controller achieves below mentioned functionalities:
1. Listing team members
2. Adding participants to teams
3. Removing participants from teams
4. Updating participants' duties within teams
5. Providing autocomplete suggestions for participant names when adding new members
6. Bulk deletion of team members
For the next project deliverable, we plan to achieve below mentioned functionalities:
1. Modifying the TeamsUsersController to TeamsParticipantsController and respectively modifying the associations and related methods and classes
2. We plan to achieve separation of concerns between models and classes and aim to minimize coupling
3. More test cases and test suites will be implement to test the robustness and effectiveness of the changes modified
4. Achieving code readability and maintainability by providing descriptive comments wherever necessary and maintaining consistent naming conventions for variables
Problem Description
Currently our controller presents with below mentioned major issues:
1. Incorrect Association Representation: The TeamsUser model links a User with a Team , not taking into consideration whether the User is assigned with a course or an assignment and generating ambiguity.
2. Violation of SOLID/DRY Principles: The methods in the controllers are very long and contain unnecessary logic and redundant code
3. Tight Coupling: Currently, there is a business logic code that resides in the model whereas it should have been placed in the controller. This results in a higher coupling and introduces difficulties in the future while modifying code.
4. Inconsistent code quality: Many places in the code have inconsistent naming conventions for the variables.
5. Insufficient Testing: Currently, testing has not been performed to a great extent and so the effectiveness of the existing codebase cannot be determined.
Scope of Work
The current work will involve the below implementation effort:
1. Model Refactoring
- Replace TeamsUsers controller with TeamsParticipants
- Update the database association structure to link TeamsParticipant with Partipant and Team
2. Controller Redesign
- Reimplementing a new TeamsParticipantsController which handles associations between teams and participants and achieves all functionalities listed in above section
- Ensure controller actions focus on request/response handling and delegating business logic to models
3. Create Method Refactor
- Breaking down create method in the controller into smaller, reusable, testable private methods
- Eliminate code duplication and unnecessary nesting
4. Model Enhancements
- Using the concept of polymorphism to clearly handle team membership and association rules
- Introducing checks related to whether a user is part of multiple teams and ensuring this is satisfied only in case of a mentor who can be assigned multiple teams
5. Code Quality Improvements
- Ensuring consistent naming conventions for variables
- Descriptive comments to make code more reliable and understandable
- Applying code best practises throughout codebase to ensure consistency
6. Testing
- Including RSpec tests for each controller method (e.g. index, create, delete etc.)
- Implement tests in models wherever additional business logic has been added
- Perform manual testing to ensure feature completeness and correctness
7. Documentation
- A detailed documentation providing the behavior of the controller and what it tries to achieve
- It should also include the associations between different entities and model and controller interactions
Changes Proposed
Summary of Refactor
- Replaced all references to
TeamsUser
withTeamsParticipant
.
- Refactored long methods (especially
create
) into smaller private methods.
- Moved business logic to
AssignmentTeam
andMentoredTeam
where appropriate (e.g., mentor-specific rules).
- Removed unnecessary nesting in methods like
create
.
- Improved naming conventions for all variables.
- Enhanced comments to explain functionality clearly.
- Ensured SOLID Principles are followed across all code.
- Wrote new unit and integration tests for controller methods.
Proposed Flow for Major Methods
index
Input: team_id
Action: Find team → Retrieve associated participants → Render list (JSON or HTML view).
Notes: Simplicity focus: Only data retrieval, no complex logic.
create
Input: Participant information, team_id
Steps:
Validate participant (exists, belongs to assignment/course).
Check team eligibility:
If participant is already on another team → Validate mentor exception rules (handled in model).
Create TeamsParticipant
record linking the participant and team.
Handle success/failure gracefully with appropriate responses.
Important: Keep business rules outside the controller wherever possible (delegate to model methods).
destroy
Input: teams_participant_id
Action: Remove participant from the team cleanly, handling foreign key constraints.
autocomplete_participants
Input: assignment_id
, search string
Action: Return a list of matching participants for the given assignment.
bulk_delete
Input: List of participant IDs
Action: Mass remove participants from their teams, validate permissions.
Helper Methods (Private)
find_team
find_participant
validate_participant_eligibility
add_participant_to_team
remove_participant_from_team
mentor_eligibility_check
(Delegated to AssignmentTeam
/ MentoredTeam
)
Each method will have a clear single responsibility and promote reuse across the controller.
Notes on Migration
All foreign keys linking teams to users will point through TeamsParticipants
, not TeamsUsers
.
Update any related services or background jobs that previously depended on TeamsUser
.
Backward compatibility should be evaluated carefully to avoid breaking existing assignments or teams during the migration phase.
Files Changed
TeamsParticipantsController
Method | Change | Reason |
---|---|---|
action_allowed? | No Change | Determines if the current user has the necessary privileges to perform the requested action. |
auto_complete_for_user_name | No Change | Provides a list of possible team members based on a partial name search for autocomplete functionality. |
update_duties | No Change | Updates the duty assigned to a participant within a team and redirects to the student's team view. |
list | No Change | Displays all participants of a specific team with pagination support. |
new | No Change | Prepares the form for adding a new participant. |
create | Refactored | Validates eligibility before adding a participant; delegates business logic. |
delete | Refactored | Removes participant cleanly with undo option. |
delete_selected | New | Bulk deletes multiple participants from a team. |
user_not_found_message (private) | New | Returns a specific message if a user is not found. |
valid_participant? (private) | New | Checks eligibility of participant for assignment/course. |
participant_not_found_message (private) | New | Provides feedback if participant not linked to assignment/course. |
AssignmentTeam.rb
Method | Change | Reason |
---|---|---|
user_id(current_user = nil) | Modified | Added optional current_user param for better flexibility. |
set_current_user | Removed | Logic merged into user_id. |
includes?(participant) | Retained (Minor rewording) | Direct comparison with updated participant fetching logic. |
parent_model | Retained | Returns 'Assignment' as parent model. |
self.parent_model(id) | Removed | Responsibility moved elsewhere for separation of concerns. |
fullname | Removed | Deemed unnecessary alias. |
review_map_type | Removed | Hardcoding removed to reduce tight coupling. |
prototype | Removed | Not needed under Rails ActiveRecord conventions. |
assign_reviewer | Modified | Extracted review map creation into create_review_map. |
create_review_map | New | Dedicated method for creating review maps. |
get_reviewer | Removed | Reviewer assignment simplified. |
reviewed_by? | Modified | Now uses ReviewResponseMap.exists? for better DB efficiency. |
topic | Removed | Responsibility split for cleaner structure. |
has_submissions? | Retained | Basic file/submission existence checks. |
participants | Modified | Refactored using TeamsParticipant.team_members(id). |
add_participant | Modified | Creates a TeamsParticipant directly. |
delete & destroy | Removed | Simplified elsewhere. |
first_member | Removed | SRP enforcement. |
submitted_files(path) | Removed | File access logic shifted to service. |
import/export methods | Removed | Responsibility moved to helpers/services. |
copy(course_id) | Removed | Refactored externally. |
hyperlinks | Removed | Delegated to service. |
submit_hyperlink(hyperlink) | Modified (Delegated) | Handled by TeamFileService. |
remove_hyperlink(hyperlink) | Modified (Delegated) | Handled by TeamFileService. |
files(directory) | Removed | File traversal extracted. |
team(participant) | Removed | Moved to higher-level service. |
export_fields(options) | Removed | Offloaded for SRP. |
remove_team_by_id(id) | Removed | Refactored. |
path | Removed | File path responsibility shifted. |
set_student_directory_num | Removed | Directory numbering moved. |
received_any_peer_review? | Removed | Simplified elsewhere. |
most_recent_submission | Retained (Optimized) | Improved query efficiency. |
get_logged_in_reviewer_id(current_user_id) | Removed | Participant-reviewer handling refactored. |
current_user_is_reviewer?(current_user_id) | Removed | Responsibility simplified. |
create_new_team(user_id, signuptopic) | Modified (Simplified) | Refactored for better exception handling. |
MentoredTeam.rb
Method | Change | Reason |
---|---|---|
add_member(user, _assignment_id = nil) | Refactored | Broken into modular private methods for adding users and assigning mentors. |
import_team_members(row_hash) | Refactored | Improved to skip blanks, safe user lookup, and error handling. |
can_add_member?(user) | New | Private method for team capacity and mentor assignment validation. |
add_team_user(user) | New | Cleanly adds a TeamsUser. |
add_participant_to_team(user) | New | Adds participant based on assignment. |
assign_mentor_if_needed(_assignment_id) | New | Ensures no duplicate mentors are assigned. |
mentor_assignment_valid?(user) | New | Validates mentor assignment rules. |
user_not_in_team?(user) | New | Checks if user is already part of the team. |
find_or_raise_user(teammate) | New | Finds user or raises informative ImportError. |
TeamsParticipants Model
Aspect | Change | Reason |
---|---|---|
Association | New | Establishes direct link between Participant and Team to maintain integrity. |
team_members | New | Retrieves all users associated through participants. |
remove_participant_from_team | New | Safely removes participant from team. |
username delegation | New | Delegates access to participant's username. |
Integrity | New | Ensures only valid assignment participants can join teams. |
Maintainability | New | Designed to align with SOLID principles and Rails best practices. |
Testing Plan
We plan to cover the reimplementation and refactoring of the following:
- AssignmentTeam
- MentoredTeam
- TeamsParticipantsController
- TeamsParticipant model
We use RSpec for model, controller, and request specs. API tests are also included where applicable. Both positive and negative test cases are included to ensure robust functionality, along with validation checks and authorization verifications.
AssignmentTeam Model Tests
# | Method | Test Description |
---|---|---|
1 | user_id | Verify that the correct user ID is returned; prioritize current user if available. |
2 | includes? | Check if a given participant is part of the team. |
3 | parent_model | Ensure the parent model returns "Assignment". |
4 | assign_reviewer | Test reviewer assignment creation and error handling when assignment is not found. |
5 | create_review_map | Confirm a new ReviewResponseMap record is created successfully. |
6 | reviewed_by? | Verify if a reviewer has reviewed the team; test both true and false scenarios. |
7 | participants | Ensure the correct participants are retrieved via TeamsParticipant. |
8 | add_participant | Confirm that a participant is added, and prevent duplicate addition. |
9 | create_new_team | Ensure that a new team-user linkage, sign-up, and nodes are created properly. |
10 | submit_hyperlink | Verify delegation to TeamFileService for hyperlink submission. |
11 | remove_hyperlink | Verify delegation to TeamFileService for hyperlink removal. |
12 | has_submissions? | Check behavior when team has submissions and when it doesn't. |
13 | most_recent_submission | Ensure the most recent submission is retrieved based on updated_at. |
MentoredTeam Model Tests
# | Method | Test Description |
---|---|---|
1 | import_team_members | Ensure team members are imported from a list correctly. |
2 | find_or_raise_user | Test for successful user lookup and error raising if user not found. |
3 | user_not_in_team? | Confirm whether a user is already in the team or not. |
4 | mentor_assignment_valid? | Verify that a mentor can be assigned properly and prevent duplicate mentors. |
5 | add_member | Ensure user is added successfully and prevent re-adding existing team members. |
6 | can_add_member? | Verify team capacity check before adding a member. |
7 | add_team_user | Ensure that a TeamsUser is created and linked correctly. |
8 | add_participant_to_team | Confirm that a participant is correctly linked to the team. |
9 | assign_mentor_if_needed | Validate that mentor is assigned only when needed (no double assignment). |
TeamsParticipantsController Tests
# | Method | Test Description |
---|---|---|
1 | valid_participant? | Confirm existence check for a participant; return true/false accordingly. |
2 | update_duties | Test participant duty update flow and ensure a redirect occurs. |
3 | user_not_found_message | Validate that a proper flash message is returned when a user isn't found. |
4 | participant_not_found_message | Validate correct error message if participant isn't linked. |
5 | create | Confirm that creating a TeamsParticipant increases record count. |
6 | list | Test that the participant list view renders correctly. |
7 | action_allowed? | Ensure access control is enforced based on user roles (admin/TA/student). |
8 | delete | Confirm deletion of a TeamsParticipant entry works correctly. |
9 | auto_complete_for_user_name | Verify that JSON autocomplete results are returned based on user input. |
10 | new | Test that the new participant view loads successfully. |
11 | delete_selected | Ensure multiple TeamsParticipant records can be deleted at once. |
TeamsParticipant Model Tests
# | Method | Test Description |
---|---|---|
1 | Associations | Ensure that a TeamsParticipant correctly belongs to a team and participant. |
2 | Validations | Confirm presence validations on team and participant relationships. |
3 | team_members | Validate fetching all team members given a team ID. |
4 | participant? | Verify participant existence check for a given user; test positive and negative cases. |
TeamsParticipants API (Request Specs)
# | Endpoint | Test Description |
---|---|---|
1 | POST /teams_participants | Ensure a participant is added via API and redirects successfully. |
2 | DELETE /teams_participants/:id | Ensure a participant is deleted via API and redirects successfully. |
Pull request
Mentor
- Vihar Manojkumar Shah(vshah23@ncsu.edu)
Team Members
- Manav Kamdar (mkamdar@ncsu.edu)
- Aditya Singh (asingh78@ncsu.edu)
- Shivang Patel (spatel74@ncsu.edu)