<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cmehta</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cmehta"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Cmehta"/>
	<updated>2026-05-17T12:14:35Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2083._Revision_planning_tool_E2016&amp;diff=136318</id>
		<title>CSC/ECE 517 Fall 2020 - E2083. Revision planning tool E2016</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2083._Revision_planning_tool_E2016&amp;diff=136318"/>
		<updated>2020-10-28T01:42:41Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Rounds of peer reviews may be implemented between submissions for assignments on Expertiza. In order to better track the implementation of reviewer's suggestions, a Revision Planning Tool should be implemented.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. We could carry the interaction one step further if we asked authors to make up a revision plan based on the first-round reviews. That is, authors would say what they were planning to do to improve their work. Then second-round reviewers would assess how well they did it. In essence, this means that authors would be adding criteria to the second-round rubric that applied only to their submission. We are interested in having this implemented and used in a class so that we can study its effect.&lt;br /&gt;
&lt;br /&gt;
===Previous Implementations===&lt;br /&gt;
Revision planning has been implemented twice before, once in [https://expertiza.csc.ncsu.edu/index.php/E1875_Revision_Planning_Tool E1875] and once in [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Spring_2020_E2016_Revision_planning_tool E2016]. While the functionality worked and effectively minimized changes to the code, they also had the following problems:&lt;br /&gt;
*Hardcoded “round” numbers in many places of the code.&lt;br /&gt;
*Documentation does not reflect the new changes they made.&lt;br /&gt;
*Revision planning responses and responses to the other items are not distinguished in heatgrid view.&lt;br /&gt;
*The idea of adding a &amp;lt;code&amp;gt;team_id&amp;lt;/code&amp;gt; field to each question is intuitive. However, they failed to come up with a clean implementation of this idea. Specifically, they had passed some trailing parameters several methods down before reaching the place that needs them.&lt;br /&gt;
&lt;br /&gt;
===Rationale===&lt;br /&gt;
To implement revision planning, [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Spring_2020_E2016_Revision_planning_tool E2016] added &amp;lt;code&amp;gt;EnableRevisionPlan&amp;lt;/code&amp;gt; (boolean) to &amp;lt;code&amp;gt;Assignment&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;TeamID&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;Question&amp;lt;/code&amp;gt;.  Adding a boolean to enable revision planning for an assignment makes sense, but having certain questions belong to a team is not a clean implementation. Instead, we will create a new questionnaire that will belong to each team and keep track of the set of questions. We will use this new questionnaire to separate the revision plan responses and responses to other items in heatgrid view by creating a different table for each.&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
===Database Design===&lt;br /&gt;
Items in green are additions.&lt;br /&gt;
[[File:E2083_Proposed_Design.png|1000px|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the assignment table we will add &amp;lt;code&amp;gt;is_revision_enabled?&amp;lt;/code&amp;gt; column to indicate whether the assignment accepts a revision plan along with review rubric.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RevisionPlanQuestionnaire&amp;lt;/code&amp;gt; maps a questionnaire to an assignment team and round. This will map to a questionnaire that will be created by the reviewee.&lt;br /&gt;
&lt;br /&gt;
===Proposed Changes===&lt;br /&gt;
# A team would be allowed to create a &amp;lt;code&amp;gt;RevisionPlanQuestionnaire&amp;lt;/code&amp;gt; after completion of round 1 of review. This revision plan questionnaire would be linked to the next round and to the team. Team would be able to add questions to this revision plan questionnaire. &lt;br /&gt;
# Reviewer would be displayed questions of both the original assignment review rubric and reviewee created revision plan. To achieve this we will create a &amp;lt;code&amp;gt;CompositeQuestionnaire&amp;lt;/code&amp;gt; by combining the two questionnaires. This composite questionnaire would not have any revision plan or review rubric based code. &lt;br /&gt;
#* Composite questionnaire will be created in the following:&lt;br /&gt;
## When revision plan is enabled and a questionnaire is requested from &amp;lt;code&amp;gt;ReviewResponseMap&amp;lt;/code&amp;gt;.&lt;br /&gt;
## When revision plan is enabled and questionnaire is requested from response.&lt;br /&gt;
#* Composite questionnaire would have a function &amp;lt;code&amp;gt;questions&amp;lt;/code&amp;gt; to return questions of contained questionnaires.&lt;br /&gt;
# The Response currently displays section headings using &amp;lt;code&amp;gt;SectionHeader&amp;lt;/code&amp;gt;. SectionHeader is a child class of &amp;lt;code&amp;gt;QuestionnaireHeader&amp;lt;/code&amp;gt; which itself derives from &amp;lt;code&amp;gt;Question&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt; A new &amp;lt;code&amp;gt;QuestionnaireNameHeader&amp;lt;/code&amp;gt; class which derives from QuestionnaireHeader will be created to display name of Questionnaire (Improvement Plan/Assignment) in a way which is similar to how we show section headings in UI.&lt;br /&gt;
&lt;br /&gt;
===User Interface===&lt;br /&gt;
====Enable Revision Planning====&lt;br /&gt;
In order to enable '''Revision Planning''', the setting must be enabled when creating or editing an assignment under the '''General''' tab.  The wireframe below demonstrates creating an assignment, and editing the assignment functions similarly.  '''Improvement plan?''' should be checked to enable this option. &lt;br /&gt;
&lt;br /&gt;
[[File:Enable_Revision_Planning_Wireframe.png|700px|thumb|center|Wireframe of Enabling Assignment's Revision Planning]]&lt;br /&gt;
&lt;br /&gt;
====Assignment Overview Page (contains the Link to the revision planning page)====&lt;br /&gt;
The '''Revision Planning''' link is available to students during every submission period (except the first round submission) and not available during every review period. As shown in the wireframe, by clicking '''Revision Planning''' students would be redirected to a page explained under the ‘Revision planning page’ subsection.&lt;br /&gt;
&lt;br /&gt;
[[File:Link_to_the_revision_planning.jpeg|600px|thumb|center|Wireframe of Assignment Overview Page]]&lt;br /&gt;
&lt;br /&gt;
====Editing the Revision Plan Questionnaire====&lt;br /&gt;
After creating the Revision Plan Questionnaire, it must be edited.  Questions can be added by specifying the amount of questions and their type.  Questions can be removed by clicking '''Remove''' in the leftmost column.  Once the questionnaire is complete, it can be saved.  This page will be visible during each submission period after the first and will be unavailable during all review periods. &lt;br /&gt;
 &lt;br /&gt;
[[File:Edit_Revision_Plan_Wireframe.png|600px|thumb|center|Wireframe of Editing an Assignment's Revision Plan]]&lt;br /&gt;
&lt;br /&gt;
====Summary Report Page====&lt;br /&gt;
When a project has been reviewed at least once, a participant will be able to view their team's score.  The wireframe below shows what this will look like after the second round of reviews.  For the second and all subsequent reviews, the results of questions that were created by the instructor will be shown under '''Assignment Questionnaire.'''  The results of the questions created by the team will be shown under '''Improvement Plan.'''&lt;br /&gt;
&lt;br /&gt;
[[File:View_Scores_Wireframe.png|400px|thumb|center|Wireframe of Summary Report for an Assignment]]&lt;br /&gt;
&lt;br /&gt;
===Control Flow Diagram===&lt;br /&gt;
[[File:Revision Planning Control Flow Diagram.jpeg|400px|thumb|center|Control Flow of the Revision Planning Function]]&lt;br /&gt;
&lt;br /&gt;
===Test Plan===&lt;br /&gt;
&lt;br /&gt;
====RSpec Testing====&lt;br /&gt;
The RSpec tests would test both controller and models.&lt;br /&gt;
&lt;br /&gt;
Controllers&lt;br /&gt;
* spec/controllers/questionnaires_controller_spec.rb: test revision plan questionnaire can be created and edited.&lt;br /&gt;
* spec/controllers/assignments_controller_spec.rb: create and validate an assignment with revision planning enabled.&lt;br /&gt;
&lt;br /&gt;
Models&lt;br /&gt;
Test validations and logic present in revision plan and composite questionnaire models.&lt;br /&gt;
* spec/models/revision_plan_questionnaire_spec.rb&lt;br /&gt;
* spec/models/composite_questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
====Manual Testing====&lt;br /&gt;
Manual testing will aim to verify the following:&lt;br /&gt;
* Create an assignment with revision planning enabled.&lt;br /&gt;
* Are participants allowed to create/edit revision plan when round 1+ (1 or greater than 1) reviews have finished.&lt;br /&gt;
* Is revision plan editing disabled when assignment is in review stage.&lt;br /&gt;
* Are reviewers shown questions created by reviewees.&lt;br /&gt;
* Are participants shown summary of score for revision plan after review deadline has expired.&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
Chaitanya Mehta (cmehta)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Darby Madewell (demadewe)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Dongni Yang (dyang23)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Sidharth Mehta (smehta22)&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
'''Mentor:''' Yulin Zhang (yzhan114)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# Previous Implementation: [https://expertiza.csc.ncsu.edu/index.php/E1875_Revision_Planning_Tool E1875 wiki], [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Spring_2020_E2016_Revision_planning_tool E2016 wiki] &lt;br /&gt;
# Forked Repository: [https://github.com/SidharthMehta/expertiza/tree/beta E2083 github]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2083._Revision_planning_tool_E2016&amp;diff=136212</id>
		<title>CSC/ECE 517 Fall 2020 - E2083. Revision planning tool E2016</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2083._Revision_planning_tool_E2016&amp;diff=136212"/>
		<updated>2020-10-23T21:06:44Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* Database Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Rounds of peer reviews may be implemented between submissions for assignments on Expertiza.  In order to better track the implementation of reviewer's suggestions, a Revision Planning Tool should be implemented.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. We could carry the interaction one step further if we asked authors to make up a revision plan based on the first-round reviews. That is, authors would say what they were planning to do to improve their work. Then second-round reviewers would assess how well they did it. In essence, this means that authors would be adding criteria to the second-round rubric that applied only to their submission. We are interested in having this implemented and used in a class so that we can study its effect.&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
===Database Design===&lt;br /&gt;
Items in green are additions.&lt;br /&gt;
[[File:E2083_Proposed_Design.png|1000px|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the assignment table we will add &amp;lt;code&amp;gt;is_revision_enabled?&amp;lt;/code&amp;gt; column to indicate whether the assignment accepts a revision plan along with review rubric.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RevisionPlanQuestionnaire&amp;lt;/code&amp;gt; maps a questionnaire to an assignment team and round. This will map to a questionnaire that will be created by the reviewee.&lt;br /&gt;
&lt;br /&gt;
===Proposed Changes===&lt;br /&gt;
# A team would be allowed to create a &amp;lt;code&amp;gt;RevisionPlanQuestionnaire&amp;lt;/code&amp;gt; after completion of round 1 of review. This revision plan questionnaire would be linked to the next round and to the team. Team would be able to add questions to this revision plan questionnaire. &lt;br /&gt;
# Reviewer would be displayed questions of both the original assignment review rubric and reviewee created revision plan. To achieve this we will create a &amp;lt;code&amp;gt;CompositeQuestionnaire&amp;lt;/code&amp;gt; by combining the two questionnaires. This composite questionnaire would not have any revision plan or review rubric based code. &lt;br /&gt;
#* Composite questionnaire will be created in the following:&lt;br /&gt;
## When revision plan is enabled and a questionnaire is requested from &amp;lt;code&amp;gt;ReviewResponseMap&amp;lt;/code&amp;gt;.&lt;br /&gt;
## When revision plan is enabled and questionnaire is requested from response.&lt;br /&gt;
#* Composite questionnaire would have a function &amp;lt;code&amp;gt;questions&amp;lt;/code&amp;gt; to return questions of contained questionnaires.&lt;br /&gt;
# The Response currently displays section headings using &amp;lt;code&amp;gt;SectionHeader&amp;lt;/code&amp;gt;. SectionHeader is a child class of &amp;lt;code&amp;gt;QuestionnaireHeader&amp;lt;/code&amp;gt; which itself derives from &amp;lt;code&amp;gt;Question&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt; A new &amp;lt;code&amp;gt;QuestionnaireNameHeader&amp;lt;/code&amp;gt; class which derives from QuestionnaireHeader will be created to display name of Questionnaire (Improvement Plan/Assignment) in a way which is similar to how we show section headings in UI.&lt;br /&gt;
&lt;br /&gt;
===User Interface===&lt;br /&gt;
====Enable Revision Planning====&lt;br /&gt;
In order to enable '''Revision Planning''', the setting must be enabled when creating or editing an assignment under the '''General''' tab.  The wireframe below demonstrates creating an assignment, and editing the assignment functions similarly.  '''Improvement plan?''' should be checked to enable this option. &lt;br /&gt;
&lt;br /&gt;
[[File:Enable_Revision_Planning_Wireframe.png|700px|thumb|center|Wireframe of Enabling Assignment's Revision Planning]]&lt;br /&gt;
&lt;br /&gt;
====Assignment Overview Page (contains the Link to the revision planning page)====&lt;br /&gt;
The '''Revision Planning''' link is available to students during every submission period (except the first round submission) and not available during every review period. As shown in the wireframe, by clicking '''Revision Planning''' students would be redirected to a page explained under the ‘Revision planning page’ subsection.&lt;br /&gt;
&lt;br /&gt;
[[File:Link_to_the_revision_planning.jpeg|600px|thumb|center|Wireframe of Assignment Overview Page]]&lt;br /&gt;
&lt;br /&gt;
====Editing the Revision Plan Questionnaire====&lt;br /&gt;
After creating the Revision Plan Questionnaire, it must be edited.  Questions can be added by specifying the amount of questions and their type.  Questions can be removed by clicking '''Remove''' in the leftmost column.  Once the questionnaire is complete, it can be saved.  This page will be visible during each submission period after the first and will be unavailable during all review periods. &lt;br /&gt;
 &lt;br /&gt;
[[File:Edit_Revision_Plan_Wireframe.png|600px|thumb|center|Wireframe of Editing an Assignment's Revision Plan]]&lt;br /&gt;
&lt;br /&gt;
====Summary Report Page====&lt;br /&gt;
When a project has been reviewed at least once, a participant will be able to view their team's score.  The wireframe below shows what this will look like after the second round of reviews.  For the second and all subsequent reviews, the results of questions that were created by the instructor will be shown under '''Assignment Questionnaire.'''  The results of the questions created by the team will be shown under '''Improvement Plan.'''&lt;br /&gt;
&lt;br /&gt;
[[File:View_Scores_Wireframe.png|400px|thumb|center|Wireframe of Summary Report for an Assignment]]&lt;br /&gt;
&lt;br /&gt;
===Control Flow Diagram===&lt;br /&gt;
[[File:Revision Planning Control Flow Diagram.jpeg|400px|thumb|center|Control Flow of the Revision Planning Function]]&lt;br /&gt;
&lt;br /&gt;
===Test Plan===&lt;br /&gt;
Under development.&lt;br /&gt;
&lt;br /&gt;
We will be using RSPEC to test both controller and models.&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
Chaitanya Mehta (cmehta)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Darby Madewell (demadewe)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Dongni Yang (dyang23)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Sidharth Mehta (smehta22)&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
'''Mentor:''' Yulin Zhang (yzhan114)&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2083._Revision_planning_tool_E2016&amp;diff=135877</id>
		<title>CSC/ECE 517 Fall 2020 - E2083. Revision planning tool E2016</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2083._Revision_planning_tool_E2016&amp;diff=135877"/>
		<updated>2020-10-21T01:46:03Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* Database Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Rounds of peer reviews may be implemented between submissions for assignments on Expertiza.  In order to better track the implementation of reviewer's suggestions, a Revision Planning Tool should be implemented.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. We could carry the interaction one step further if we asked authors to make up a revision plan based on the first-round reviews. That is, authors would say what they were planning to do to improve their work. Then second-round reviewers would assess how well they did it. In essence, this means that authors would be adding criteria to the second-round rubric that applied only to their submission. We are interested in having this implemented and used in a class so that we can study its effect.&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
===Database Design===&lt;br /&gt;
[[File:E2083_Proposed_Design.png|1000px|thumb|center|Database design]]&lt;br /&gt;
&lt;br /&gt;
===Proposed Changes===&lt;br /&gt;
===User Interface===&lt;br /&gt;
====Assignment Overview Page (contains the Link to the revision planning page)====&lt;br /&gt;
The '''Revision Planning''' link is available to students during every submission period (except the first round submission) and not available during every review period. As shown in the wireframe, by clicking '''Revision Planning''' students would be redirected to a page explained under the ‘Revision planning page’ subsection.&lt;br /&gt;
&lt;br /&gt;
[[File:Link_to_the_revision_planning.jpeg|600px|thumb|center|Wireframe of Assignment Overview Page]]&lt;br /&gt;
&lt;br /&gt;
====Editing the Revision Plan Questionnaire====&lt;br /&gt;
After creating the Revision Plan Questionnaire, it must be edited.  Questions can be added by specifying the amount of questions and their type.  Questions can be removed by clicking &amp;quot;Remove&amp;quot; in the leftmost column.  Once the questionnaire is complete, it can be saved.  This page will be visible during each submission period after the first and will be unavailable during all review periods.  &lt;br /&gt;
[[File:Edit_Revision_Plan_Wireframe.png|600px|thumb|center|Wireframe of Editing an Assignment's Revision Plan]]&lt;br /&gt;
&lt;br /&gt;
====Summary Report Page====&lt;br /&gt;
When a project has been reviewed at least once, a participant will be able to view their team's score.  The wireframe below shows what this will look like after the second round of reviews.  For the second and all subsequent reviews, the results of questions that were created by the instructor will be shown under &amp;quot;Assignment Questionnaire.&amp;quot;  The results of the questions created by the team will be shown under &amp;quot;Improvement Plan.&amp;quot;&lt;br /&gt;
[[File:View_Scores_Wireframe.png|400px|thumb|center|Wireframe of Summary Report for an Assignment]]&lt;br /&gt;
&lt;br /&gt;
===Control Flow Diagram===&lt;br /&gt;
[[File:Revision Planning Control Flow Diagram.jpeg|400px|thumb|center|Control Flow of the Revision Planning Function]]&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
Chaitanya Mehta (cmehta)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Darby Madewell (demadewe)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Dongni Yang (dyang23)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Sidharth Mehta (smehta22)&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
'''Mentor:''' Yulin Zhang (yzhan114)&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134748</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134748"/>
		<updated>2020-10-12T22:01:26Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
==Task Identified==&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
Expertiza already had well written test cases for lottery controller. While moving methods to model some of these test cases were moved as well. After refactoring the controller, it was tested manually and using previously written RSpec tests to ensure that no bugs were introduced.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there is a drop of 0.004% in coverage all the code that belongs to lottery_controller and which was moved to models has 100% test coverage. Overall coverage might have reduced because total lines have reduced.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' &lt;br /&gt;
# If there are no non signed up teams that have bids for topics, then a 500 Internal Server Error is displayed.&lt;br /&gt;
# When intelligent assignment finishes it disables bidding on topics, bidding on topics needs to be enabled to run intelligent assignment.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
'''Steps to signup students for topics:'''&lt;br /&gt;
* Impersonate a participant.&lt;br /&gt;
* Select assignment with topics. (for example lottery assignment)&lt;br /&gt;
* Open '''Signup sheet'''.&lt;br /&gt;
* Drag and drop topics under selection section.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
Chaitanya Mehta (cmehta)&lt;br /&gt;
&amp;lt;br&amp;gt; Sidharth Mehta (smehta22)&lt;br /&gt;
&amp;lt;br&amp;gt; '''Mentor:''' Sahil Papalkar (spapalk)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134747</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134747"/>
		<updated>2020-10-12T22:00:03Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
==Task Identified==&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
Expertiza already had well written test cases for lottery controller. While moving methods to model some of these test cases were moved as well. After refactoring the controller, it was tested manually and using previously written RSpec tests to ensure that no bugs were introduced.&lt;br /&gt;
Note: Although there is a drop of 0.004% in coverage all the code that belongs to lottery_controller and which was moved to models has 100% test coverage. Overall coverage might have reduced because total lines have reduced.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' &lt;br /&gt;
# If there are no non signed up teams that have bids for topics, then a 500 Internal Server Error is displayed.&lt;br /&gt;
# When intelligent assignment finishes it disables bidding on topics, bidding on topics needs to be enabled to run intelligent assignment.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
'''Steps to signup students for topics:'''&lt;br /&gt;
* Impersonate a participant.&lt;br /&gt;
* Select assignment with topics. (for example lottery assignment)&lt;br /&gt;
* Open '''Signup sheet'''.&lt;br /&gt;
* Drag and drop topics under selection section.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
Chaitanya Mehta (cmehta)&lt;br /&gt;
&amp;lt;br&amp;gt; Sidharth Mehta (smehta22)&lt;br /&gt;
&amp;lt;br&amp;gt; '''Mentor:''' Sahil Papalkar (spapalk)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134746</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134746"/>
		<updated>2020-10-12T21:03:30Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
==Task Identified==&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
Expertiza already had well written test cases for lottery controller. While moving methods to model some of these test cases were moved as well. After refactoring the controller, it was tested manually and using previously written RSpec tests to ensure that no bugs were introduced.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' &lt;br /&gt;
# If there are no non signed up teams that have bids for topics, then a 500 Internal Server Error is displayed.&lt;br /&gt;
# When intelligent assignment finishes it disables bidding on topics, bidding on topics needs to be enabled to run intelligent assignment.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
'''Steps to signup students for topics:'''&lt;br /&gt;
* Impersonate a participant.&lt;br /&gt;
* Select assignment with topics. (for example lottery assignment)&lt;br /&gt;
* Open '''Signup sheet'''.&lt;br /&gt;
* Drag and drop topics under selection section.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
Chaitanya Mehta (cmehta)&lt;br /&gt;
&amp;lt;br&amp;gt; Sidharth Mehta (smehta22)&lt;br /&gt;
&amp;lt;br&amp;gt; '''Mentor:''' Sahil Papalkar (spapalk)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134744</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134744"/>
		<updated>2020-10-12T21:01:17Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
==Task Identified==&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
Expertiza already has well written test cases for lottery controller. While moving methods to model some of these test cases were moved as well. After making changes the application was tested manually and using previously written RSpec test to ensure that no bugs were introduced.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' &lt;br /&gt;
# If there are no non signed up teams that have bids for topics, then a 500 Internal Server Error is displayed.&lt;br /&gt;
# When intelligent assignment finishes it disables bidding on topics, bidding on topics needs to be enabled to run intelligent assignment.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
'''Steps to signup students for topics:'''&lt;br /&gt;
* Impersonate a participant.&lt;br /&gt;
* Select assignment with topics. (for example lottery assignment)&lt;br /&gt;
* Open '''Signup sheet'''.&lt;br /&gt;
* Drag and drop topics under selection section.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
Chaitanya Mehta (cmehta)&lt;br /&gt;
&amp;lt;br&amp;gt; Sidharth Mehta (smehta22)&lt;br /&gt;
&amp;lt;br&amp;gt; '''Mentor:''' Sahil Papalkar (spapalk)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134743</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134743"/>
		<updated>2020-10-12T20:52:59Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* Team Members */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
==Task Identified==&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' &lt;br /&gt;
# If there are no non signed up teams that have bids for topics, then a 500 Internal Server Error is displayed.&lt;br /&gt;
# When intelligent assignment finishes it disables bidding on topics, bidding on topics needs to be enabled to run intelligent assignment.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
'''Steps to signup students for topics:'''&lt;br /&gt;
* Impersonate a participant.&lt;br /&gt;
* Select assignment with topics. (for example lottery assignment)&lt;br /&gt;
* Open '''Signup sheet'''.&lt;br /&gt;
* Drag and drop topics under selection section.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
Chaitanya Mehta (cmehta)&lt;br /&gt;
&amp;lt;br&amp;gt; Sidharth Mehta (smehta22)&lt;br /&gt;
&amp;lt;br&amp;gt; '''Mentor:''' Sahil Papalkar (spapalk)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134742</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134742"/>
		<updated>2020-10-12T20:45:21Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* Testing Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
==Task Identified==&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' &lt;br /&gt;
# If there are no non signed up teams that have bids for topics, then a 500 Internal Server Error is displayed.&lt;br /&gt;
# When intelligent assignment finishes it disables bidding on topics, bidding on topics needs to be enabled to run intelligent assignment.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
'''Steps to signup students for topics:'''&lt;br /&gt;
* Impersonate a participant.&lt;br /&gt;
* Select assignment with topics. (for example lottery assignment)&lt;br /&gt;
* Open '''Signup sheet'''.&lt;br /&gt;
* Drag and drop topics under selection section.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
Chaitanya Mehta (cmehta)&lt;br /&gt;
Sidharth Mehta (smehta22)&lt;br /&gt;
'''Mentor:''' Sahil Papalkar (spapalk)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134741</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134741"/>
		<updated>2020-10-12T20:44:54Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
==Task Identified==&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' &lt;br /&gt;
# If there are no non signed up teams that have bids for topics, then a 500 Internal Server Error is displayed.&lt;br /&gt;
# When intelligent assignment finishes it disables bidding on topics, bidding on topics needs to be enabled to run intelligent assignment.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
'''Steps to signup students for topics:'''&lt;br /&gt;
* Impersonate a participant.&lt;br /&gt;
* Select assignment with topics. (for example lottery assignment)&lt;br /&gt;
* Open '''Signup sheet'''.&lt;br /&gt;
* Drag and drop topics under selection section.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
Chaitanya Mehta (cmehta)&lt;br /&gt;
Sidharth Mehta (smehta22)&lt;br /&gt;
'''Mentor:''' Sahil Papalkar (spapalk)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134740</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134740"/>
		<updated>2020-10-12T20:38:18Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
==Task Identified==&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' &lt;br /&gt;
# If there are no non signed up teams that have bids for topics, then a 500 Internal Server Error is displayed.&lt;br /&gt;
# When intelligent assignment finishes it disables bidding on topics, bidding on topics needs to be enabled to run intelligent assignment.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
'''Steps to signup students for topics:'''&lt;br /&gt;
* Impersonate a participant.&lt;br /&gt;
* Select assignment with topics. (for example lottery assignment)&lt;br /&gt;
* Open '''Signup sheet'''.&lt;br /&gt;
* Drag and drop topics under selection section.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134637</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134637"/>
		<updated>2020-10-12T00:37:41Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* UI Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' &lt;br /&gt;
# If there are no non signed up teams that have bids for topics, then a 500 Internal Server Error is displayed.&lt;br /&gt;
# When intelligent assignment finishes it disables bidding on topics, bidding on topics needs to be enabled to run intelligent assignment.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
'''Steps to signup students for topics:'''&lt;br /&gt;
* Impersonate a participant.&lt;br /&gt;
* Select assignment with topics. (for example lottery assignment)&lt;br /&gt;
* Open '''Signup sheet'''.&lt;br /&gt;
* Drag and drop topics under selection section.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134636</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134636"/>
		<updated>2020-10-12T00:36:03Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* UI Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' &lt;br /&gt;
# If there are no non signed up teams that have bids for topics. a 500 Internal Server Error is displayed.&lt;br /&gt;
# When intelligent assignment finishes it disables bidding on topics, bidding on topics needs to be enabled to run intelligent assignment.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
'''Steps to signup students for topics:'''&lt;br /&gt;
* Impersonate a participant.&lt;br /&gt;
* Select assignment with topics. (for example lottery assignment)&lt;br /&gt;
* Open '''Signup sheet'''.&lt;br /&gt;
* Drag and drop topics under selection section.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134635</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134635"/>
		<updated>2020-10-12T00:12:18Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click on the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' If there are no teams that have bids for topics a 500 Internal Server Error is displayed.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134634</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134634"/>
		<updated>2020-10-12T00:11:50Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' If there are no teams that have bids for topics a 500 Internal Server Error is displayed.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134633</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134633"/>
		<updated>2020-10-12T00:11:00Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
* Scroll till you reach assignment named '''lottery'''. &amp;lt;br&amp;gt; [[File:E2066_run_intelligent_assignment.png|600px]]&lt;br /&gt;
* Click the orange '''Intelligent Assignment''' button.&lt;br /&gt;
'''Note:''' If there is no team that has bids for topics a 500 Internal Server Error is displayed.&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:E2066_run_intelligent_assignment.png&amp;diff=134632</id>
		<title>File:E2066 run intelligent assignment.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:E2066_run_intelligent_assignment.png&amp;diff=134632"/>
		<updated>2020-10-11T23:52:53Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134631</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134631"/>
		<updated>2020-10-11T23:51:18Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
By following the steps below, you will be able to manually test Expertiza with E2066 fixes.&lt;br /&gt;
&lt;br /&gt;
* Login as instructor. (Username: instructor6, Password: password)&lt;br /&gt;
* From the menu bar, hover on '''Manage''' and select '''Assignments'''.&lt;br /&gt;
[[File:Example.jpg]]&lt;br /&gt;
&lt;br /&gt;
'''Steps to create an assignment with topics:'''&lt;br /&gt;
* Create a new assignment with '''Has teams?''' selected.&lt;br /&gt;
* Go back, and then edit assignment by clicking on the '''pencil''' icon.&lt;br /&gt;
* Select '''Has topics?'''&lt;br /&gt;
* Go to '''Topics''' tab and add a few of them.&lt;br /&gt;
* Enable bidding for topics.&lt;br /&gt;
* Go to '''Other stuff''' tab, select '''Add Participants''' and then '''Copy participants from course'''.&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134585</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134585"/>
		<updated>2020-10-11T21:31:23Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
It seems more appropriate for class Assignment to know how to delete empty teams that belong it. If in future there is a new workflow that requires deletion of empty teams which belong to an assignment, this would help dry out code.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function &amp;lt;code&amp;gt;remove_empty_teams&amp;lt;/code&amp;gt; to assignment.rb.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled in Team.rb ===&lt;br /&gt;
Creation and Manipulation of Team are more suited to be model methods. Creation of team involves naming the team, creating nodes and addition of members involves creation of team user nodes. This logic should not be part of controller.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a new function &amp;lt;code&amp;gt;create_team_with_users&amp;lt;/code&amp;gt; in file team.rb and invoke it from controller.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c view code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 view code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134571</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134571"/>
		<updated>2020-10-11T18:42:09Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* RSpec */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled by Team.rb ===&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_spec.rb -e '#remove_empty_teams'&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134570</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134570"/>
		<updated>2020-10-11T18:40:20Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: /* Files Modified */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled by Team.rb ===&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/bid_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134569</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134569"/>
		<updated>2020-10-11T18:38:29Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled by Team.rb ===&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 code changes]&lt;br /&gt;
&lt;br /&gt;
==Testing Changes==&lt;br /&gt;
===RSpec===&lt;br /&gt;
Test which belong to code that has been refactored have been refactored, most of the other test relating to lottery controller remain unchanged. The following commands can be run to test lottery controller and other functions that relate to E2066.&lt;br /&gt;
    rspec ./spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
    rspec ./spec/models/bid_spec.rb&lt;br /&gt;
    rspec ./spec/models/assignment_team_spec.rb -e 'create team with users'&lt;br /&gt;
&lt;br /&gt;
===UI Testing===&lt;br /&gt;
[http://152.46.19.69:8080/ Expertiza with E2066]&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/chaitanyamehta/expertiza E2066 Repository Fork]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/1761 E2066 Pull Request]&lt;br /&gt;
#[https://www.youtube.com/channel/UCdKXzox7hrWjfOMML6FzTWg/videos Expertiza YouTube Channel]&lt;br /&gt;
#[https://www.youtube.com/watch?v=sg8n-oEIjdE YouTube tutorial for assignment with topics]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134544</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134544"/>
		<updated>2020-10-11T04:08:03Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 4: Handle deletion of empty teams related to an assignment in Assignment.rb ===&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/c61850b1d05d7ad3b44c2ba7e1fac4f4c516922e code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 5: Creation of Team with Team Members should be handled by Team.rb ===&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/be38d9ff56053c9315c2bf57aeea4a00f574918c code changes]&lt;br /&gt;
&lt;br /&gt;
=== Problem 6: Logic of merging and creating new bids should be handled by Bid.rb ===&lt;br /&gt;
Controller should not contain code to generate new bids by calculate priorities of topics using previous individual bids of users. This kind of complex logic is suited to being a model method in Bid class.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Create a class method &amp;lt;code&amp;gt;merge_bids_from_different_users&amp;lt;/code&amp;gt; which accepts team id, signup topics and bids of users, and contains logic to create bids and get priorities for new bids.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1761/commits/8d6973c1f1d3c37e31cd46c34fe316d1b38b43c2 code changes]&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134543</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134543"/>
		<updated>2020-10-11T03:43:36Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
'''Part A'''&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
'''Part A'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
'''Part B'''&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134541</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134541"/>
		<updated>2020-10-11T03:35:57Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== Problem 2: Code duplicated to create team with team nodes, add members in team ===&lt;br /&gt;
&lt;br /&gt;
The code to create an assignment team, name the team and then create a team node for the team is already handled by function &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;. This has been duplicated in lottery_controller.rb&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team = AssignmentTeam.create(name: 'Team_' + rand(10_000).to_s, parent_id: assignment.id)&lt;br /&gt;
    team_node = TeamNode.create(parent_id: assignment.id, node_object_id: new_team.id)&lt;br /&gt;
&lt;br /&gt;
AssignmentTeam also has a function &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;, which creates a TeamUser and TeamUserNode for the given user.&lt;br /&gt;
&lt;br /&gt;
    #Before&lt;br /&gt;
    new_team_user = TeamsUser.create(user_id: user_id, team_id: new_team.id)&lt;br /&gt;
    TeamUserNode.create(parent_id: team_node.id, node_object_id: new_team_user.id)&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;AssignmentTeam.create_team_and_node&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team = AssignmentTeam.create_team_and_node(assignment.id)&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;add_member(user)&amp;lt;/code&amp;gt;.&lt;br /&gt;
    #After&lt;br /&gt;
    new_team.add_member(User.find(user_id))&lt;br /&gt;
&lt;br /&gt;
=== Problem 3: Unnecessary code to explicitly delete dependents before parent is deleted ===&lt;br /&gt;
The parent objects being discussed here have association callbacks dependent destroy to correctly dispose dependents when it itself gets destroyed. We don't need to explicitly delete child objects before parent is deleted.&lt;br /&gt;
&lt;br /&gt;
====Solutions==== &lt;br /&gt;
=====Example 1=====&lt;br /&gt;
    #Before&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.team_user_node.destroy rescue nil&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;remove_user_from_previous_team&amp;lt;/code&amp;gt; explicitly deletes team_user_node before team_user is deleted. TeamUser contains code &amp;lt;code&amp;gt;has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team user is destroyed. &lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    team_user = TeamsUser.where(user_id: user_id).find {|team_user| team_user.team.parent_id == assignment_id }&lt;br /&gt;
    team_user.destroy rescue nil&lt;br /&gt;
&lt;br /&gt;
=====Example 2=====&lt;br /&gt;
    #Before&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      TeamNode.where(parent_id: assignment.id, node_object_id: team.id).destroy_all rescue nil&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
Team contains code &amp;lt;code&amp;gt;has_one :team_node, foreign_key: :node_object_id, dependent: :destroy&amp;lt;/code&amp;gt; to destroy related node when team is destroyed.&lt;br /&gt;
&lt;br /&gt;
    #After&lt;br /&gt;
    if team.teams_users.empty?&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134523</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134523"/>
		<updated>2020-10-11T02:43:30Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;code&amp;gt;create_new_teams_for_bidding_response&amp;lt;/code&amp;gt; calls merge bids once for each team member. This creates multiple bids with same topic, team and priority.&lt;br /&gt;
  &lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
Move function call to &amp;lt;code&amp;gt;merge_bids_from_different_previous_teams&amp;lt;/code&amp;gt; in outer loop, so that its called once per team.&lt;br /&gt;
&lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134520</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134520"/>
		<updated>2020-10-11T00:59:35Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids with same topic, team and priority.&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately. (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
=== Problem 1: Multiple bids created with same topic, team and priority ===&lt;br /&gt;
&lt;br /&gt;
    #before&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
        merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    #after&lt;br /&gt;
    teams.each do |user_ids|&lt;br /&gt;
      ... (code omitted)&lt;br /&gt;
      user_ids.each do |user_id|&lt;br /&gt;
        ... (code omitted)&lt;br /&gt;
      end&lt;br /&gt;
      merge_bids_from_different_previous_teams(assignment.sign_up_topics, new_team.id, user_ids, users_bidding_info)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134519</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134519"/>
		<updated>2020-10-11T00:51:23Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
# Fix bug which created multiple bids for same topic, team and priority&lt;br /&gt;
# Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately (DRY principle)&lt;br /&gt;
# Call existing Team.rb method to add members in team.&lt;br /&gt;
# Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
# Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
# Move logic for creation of team with members to Team.rb.&lt;br /&gt;
# Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Implementations==&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
* app/controllers/lottery_controller.rb &lt;br /&gt;
* app/models/assignment.rb&lt;br /&gt;
* app/models/bid.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
* spec/models/assignment_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;br /&gt;
* spec/models/assignment_team_spec.rb&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134518</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134518"/>
		<updated>2020-10-11T00:44:04Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
* Fix bug which created multiple bids for same topic, team and priority&lt;br /&gt;
* Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately (DRY principle)&lt;br /&gt;
* Call existing Team.rb method to add members in team.&lt;br /&gt;
* Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
* Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
* Move logic for creation of team with members to Team.rb.&lt;br /&gt;
* Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Problems and Solutions==&lt;br /&gt;
&lt;br /&gt;
==Files Modified==&lt;br /&gt;
*app/controllers/lottery_controller.rb &lt;br /&gt;
*app/models/assignment.rb&lt;br /&gt;
*app/models/bid.rb&lt;br /&gt;
*app/models/team.rb&lt;br /&gt;
*spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
*spec/models/assignment_spec.rb&lt;br /&gt;
*spec/models/assignment_team_spec.rb&lt;br /&gt;
*spec/models/assignment_team_spec.rb&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134517</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134517"/>
		<updated>2020-10-11T00:39:54Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;br /&gt;
&lt;br /&gt;
===Task Identified===&lt;br /&gt;
* Fix bug which created multiple bids for same topic, team and priority&lt;br /&gt;
* Call existing AssignmentTeam.rb method to create team and team node, instead of creating them separately (DRY principle)&lt;br /&gt;
* Call existing Team.rb method to add members in team.&lt;br /&gt;
* Remove code that explicitly deletes dependents before deleting object and rely on dependent destroy instead.&lt;br /&gt;
* Move logic to delete empty teams belonging to an assignment into assignment.rb.&lt;br /&gt;
* Move logic for creation of team with members to Team.rb.&lt;br /&gt;
* Move logic that merges bids of different users to Bid.rb&lt;br /&gt;
&lt;br /&gt;
==Files Affected==&lt;br /&gt;
*app/controllers/lottery_controller.rb &lt;br /&gt;
*app/models/assignment.rb&lt;br /&gt;
*app/models/bid.rb&lt;br /&gt;
*app/models/team.rb&lt;br /&gt;
*spec/controllers/lottery_controller_spec.rb&lt;br /&gt;
*spec/models/assignment_spec.rb&lt;br /&gt;
*spec/models/assignment_team_spec.rb&lt;br /&gt;
*spec/models/assignment_team_spec.rb&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134516</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134516"/>
		<updated>2020-10-11T00:07:19Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
===About Lottery Controller===&lt;br /&gt;
The lottery controller assigns teams to topics based on the priorities the team gave to each signup topic during the bidding process. When the lottery controller is called to run its method run_intelligent_assignment, a web service is sent the bidding data from each team and returns a new list of teams, each of which is close to the maximum team size specified for the assignment. The web service coalesces teams that have similar bid data and then assigns those coalesced teams to topics, giving each team their top bid on a topic that hasn't been assigned yet. Teams with larger team sizes and more bids are assigned their topics first.&lt;br /&gt;
&lt;br /&gt;
===Motivation===&lt;br /&gt;
This class contains logic to merge bids. It also contains code that creates teams, add and removes users from team. These methods are more suited to being model methods. The As much as possible, the controller should only contain standard crud actions.&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134461</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134461"/>
		<updated>2020-10-09T22:46:15Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020&amp;diff=134460</id>
		<title>CSC/ECE 517 Fall 2020</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020&amp;diff=134460"/>
		<updated>2020-10-09T22:45:19Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Dummy URL]]&lt;br /&gt;
* [[Dummy Url2]]&lt;br /&gt;
* [[E2068]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2020 - E2062. Add test cases to review_mapping_helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb]]&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134459</id>
		<title>CSC/ECE 517 Fall 2020 - E2066. Refactor lottery controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2020_-_E2066._Refactor_lottery_controller.rb&amp;diff=134459"/>
		<updated>2020-10-09T22:41:21Z</updated>

		<summary type="html">&lt;p&gt;Cmehta: Created page with &amp;quot;==CSC/ECE 517 Fall 2019 - E2066. Refactor lottery controller.rb== This page provides a description of the Expertiza based OSS project.  __TOC__&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==CSC/ECE 517 Fall 2019 - E2066. Refactor lottery controller.rb==&lt;br /&gt;
This page provides a description of the Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;/div&gt;</summary>
		<author><name>Cmehta</name></author>
	</entry>
</feed>