<?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=Spadala</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=Spadala"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Spadala"/>
	<updated>2026-06-03T03:22:48Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122442</id>
		<title>E1908 signupsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122442"/>
		<updated>2019-03-26T02:01:11Z</updated>

		<summary type="html">&lt;p&gt;Spadala: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1908. Refactoring the Sign-up sheet Controller==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/Expertiza] is an open source project dependent on [http://rubyonrails.org/Ruby on Rails] structure. Expertiza enables the teacher to make new assignments and alter new or existing assignments. It additionally enables the educator to make a rundown of subjects the students can agree to accept. Students can shape groups in Expertiza to chip away at different undertakings and projects. Students can likewise peer audit other students' entries. Expertiza underpins accommodation crosswise over different record types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
* Improved the clarity of code by improving the variable and parameter names.&lt;br /&gt;
* Followed naming conventions throughout and renamed methods with inconsistent names including the calling methods.&lt;br /&gt;
* Rectified several unwanted if-else conditions in methods and optimized the code.&lt;br /&gt;
* Refactored all instance variables and removed unnecessarily defined variables.&lt;br /&gt;
* Removed certain unwanted flash messages that occur for some user actions.&lt;br /&gt;
* Included comments for functionalities throughout for better understanding.&lt;br /&gt;
&lt;br /&gt;
===About Sign-up sheet Controller===&lt;br /&gt;
Sign-up sheet controller contains all functions related to management of the signup sheet for an assignment function to add new topics to an assignment, edit properties of a particular topic, delete a topic, etc are included here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': Create method has an if-else condition determining if create or update should be called. Create method should not be responsible for calling update. Identify why the if-else condition exists. The if-else condition exists because the current implementation calls update if a signup sheet with the same name already exists. &lt;br /&gt;
* '''Solution''': Rectified this method by removing the call to update and flashing an error instead.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 if topic.nil?&lt;br /&gt;
      setup_new_topic&lt;br /&gt;
    else&lt;br /&gt;
      update_existing_topic topic&lt;br /&gt;
      flash[:error] = &amp;quot;The topic already exists.&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Update method has a plethora of instance variables defined before updating. These are not necessary (For e.g., look at update method of bookmarks_controller).&lt;br /&gt;
* '''Solution''': Refactored the variables not needed out.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      # Replaced unnecessary variables and save with a single update call for all the parameters&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''': Destroy has a misleading else flash message.&lt;br /&gt;
* '''Solution''': Refactored the mislleading flash messages not needed out.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   @topic.destroy&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully deleted. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = &amp;quot;The topic could not be deleted.&amp;quot;&lt;br /&gt;
      flash[:error] = &amp;quot;This topic could not be found.&amp;quot; # error message mage more specific&lt;br /&gt;
    end&lt;br /&gt;
    # changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + &amp;quot;#tabs-5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 4''': Add_signup_topics_staggered does not do anything.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #add_signup_topics_staggered calls add_signup_topics and does nothing else.&lt;br /&gt;
 def add_signup_topics_staggered&lt;br /&gt;
    add_signup_topics &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 5''': Several method names are renamed to be more intuitive.&lt;br /&gt;
* '''Solution''': load_add_signup_topics is renamed to get_assignment_data and ad_info is renamed to get_ad.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Contains links that let an admin or Instructor edit, delete, view enrolled/waitlisted members for each topic&lt;br /&gt;
  # Also contains links to delete topics and modify the deadlines for individual topics. Staggered means that different topics can have different deadlines.&lt;br /&gt;
  def add_signup_topics&lt;br /&gt;
    load_add_signup_topics(params[:id])&lt;br /&gt;
    get_assignment_data(params[:id])&lt;br /&gt;
    SignUpSheet.add_signup_topic(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @@ -109,7 +109,7 @@ def add_signup_topics_staggered&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_add_signup_topics(assignment_id)&lt;br /&gt;
  def get_assignment_data(assignment_id)&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
  @@ -374,7 +374,7 @@ def save_topic_deadlines&lt;br /&gt;
  # This method is called when a student click on the trumpet icon. So this is a bad method name. --Yang&lt;br /&gt;
  def show_team&lt;br /&gt;
    if !(assignment = Assignment.find(params[:assignment_id])).nil? and !(topic = SignUpTopic.find(params[:id])).nil?&lt;br /&gt;
      @results = ad_info(assignment.id, topic.id)&lt;br /&gt;
      @results = get_ad(assignment.id, topic.id)&lt;br /&gt;
      @results.each do |result|&lt;br /&gt;
        result.keys.each do |key|&lt;br /&gt;
          @current_team_name = result[key] if key.equal? :name&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 6''': The list method is too long and is sparsely commented.&lt;br /&gt;
* '''Solution''': Added comments.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  # function to list all topics and bids to a participant&lt;br /&gt;
  def list&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    @@ -155,6 +156,8 @@ def list&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
&lt;br /&gt;
    # If the assignment supports bidding, add all the bids of an &lt;br /&gt;
    # individual or team to the list of signed topics&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
      signed_up_topics = []&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 7''': What are the differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
* '''Solution''': Removed metod which is not required&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  # routes to new page to specficy student&lt;br /&gt;
  # Its just to specify the student, its a get request. Other than that it doesnt do anything. &lt;br /&gt;
  def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
  # its an action that usually follows the aove action, its a post request to signup the student.&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 8''': Participants variable in load_add_signup_topics actually means teams that signed up for a topic.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    # to treat all assignments as team assignments&lt;br /&gt;
    # Though called participants, @participants are actually records in signed_up_teams table, which&lt;br /&gt;
    # is a mapping table between teams and topics (waitlisted recored are also counted)&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
    @teams = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 9''': Signup_as_instructor_action has if-else ladder. &lt;br /&gt;
* '''Solution''': It has been made more elegant using a helper function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
  def signup_student user&lt;br /&gt;
    if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
      flash[:success] = &amp;quot;You have successfully signed up the student for the topic!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = &amp;quot;The student has already signed up for a topic!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = &amp;quot;That student does not exist!&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    if !user.nil? and AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
      signup_student(user);&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = &amp;quot;You have successfully signed up the student for the topic!&amp;quot;&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = &amp;quot;The student has already signed up for a topic!&amp;quot;&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = &amp;quot;The student is not registered for the assignment!&amp;quot;&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
      flash[:error] = &amp;quot;The student is not registered for the assignment!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Checks if participant has permission to delete a topic, reports errors otherwise&lt;br /&gt;
  def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadline)&lt;br /&gt;
  def can_delete_topic? is_instructor, participant, assignment, drop_topic_deadline&lt;br /&gt;
    submission_error_message = &amp;quot;&amp;quot;&lt;br /&gt;
    deadline_error_message = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   @@ -237,7 +239,7 @@ def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadli&lt;br /&gt;
    else&lt;br /&gt;
      submission_error_message = &amp;quot;You have already submitted your work, so you are not allowed to drop your topic.&amp;quot;&lt;br /&gt;
      deadline_error_message = &amp;quot;You cannot drop your topic after the drop topic deadline!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
    if !participant.team.submitted_files.empty? or !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
   @@ -246,7 +248,7 @@ def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadli&lt;br /&gt;
      flash[:error] = deadline_error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
      return false&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   @@ -274,7 +276,6 @@ def delete_signup_as_instructor&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
&lt;br /&gt;
    if can_delete_topic?(true, participant, assignment, drop_topic_deadline)&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = &amp;quot;You have successfully dropped the student from the topic!&amp;quot;&lt;br /&gt;
   @@ -481,4 +482,4 @@ def ad_info(_assignment_id, topic_id)&lt;br /&gt;
  def delete_signup_for_topic(assignment_id, topic_id, user_id)&lt;br /&gt;
    SignUpTopic.reassign_topic(user_id, assignment_id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 10''': Delete_signup and delete_signup_as_instructor have much in common and violates the DRY principle. &lt;br /&gt;
* '''Solution''': Refactored them by moving the duplicate code to a helper function.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadline)&lt;br /&gt;
    submission_error_message = &amp;quot;&amp;quot;&lt;br /&gt;
    deadline_error_message = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if is_instructor?&lt;br /&gt;
      submission_error_message = &amp;quot;The student has already submitted their work, so you are not allowed to remove them&amp;quot;&lt;br /&gt;
      deadline_error_message = &amp;quot;You cannot drop a student after the drop topic deadline!&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      submission_error_message = &amp;quot;You have already submitted your work, so you are not allowed to drop your topic.&amp;quot;&lt;br /&gt;
      deadline_error_message = &amp;quot;You cannot drop your topic after the drop topic deadline!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if !participant.team.submitted_files.empty? or !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      return false&lt;br /&gt;
    elsif !drop_topic_deadline.nil? and Time.now &amp;gt; drop_topic_deadline.due_at&lt;br /&gt;
      flash[:error] = deadline_error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
      return false&lt;br /&gt;
&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # this function is used to delete a previous signup&lt;br /&gt;
  def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
@@ -235,13 +259,7 @@ def delete_signup&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? or !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = &amp;quot;You have already submitted your work, so you are not allowed to drop your topic.&amp;quot;&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? and Time.now &amp;gt; drop_topic_deadline.due_at&lt;br /&gt;
      flash[:error] = &amp;quot;You cannot drop your topic after the drop topic deadline!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
    if can_delete_topic?(false, participant, assignment, drop_topic_deadline)&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = &amp;quot;You have successfully dropped your topic!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
@@ -256,13 +274,8 @@ def delete_signup_as_instructor&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? or !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = &amp;quot;The student has already submitted their work, so you are not allowed to remove them.&amp;quot;&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? and Time.now &amp;gt; drop_topic_deadline.due_at&lt;br /&gt;
      flash[:error] = &amp;quot;You cannot drop a student after the drop topic deadline!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
&lt;br /&gt;
    if can_delete_topic?(true, participant, assignment, drop_topic_deadline)&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = &amp;quot;You have successfully dropped the student from the topic!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#https://github.com/expertiza/expertiza&lt;br /&gt;
#http://expertiza.ncsu.edu/ The live Expertiza website&lt;/div&gt;</summary>
		<author><name>Spadala</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122427</id>
		<title>E1908 signupsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122427"/>
		<updated>2019-03-26T01:37:17Z</updated>

		<summary type="html">&lt;p&gt;Spadala: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1908. Refactoring the Sign-up sheet Controller==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/Expertiza] is an open source project dependent on [http://rubyonrails.org/Ruby on Rails] structure. Expertiza enables the teacher to make new assignments and alter new or existing assignments. It additionally enables the educator to make a rundown of subjects the students can agree to accept. Students can shape groups in Expertiza to chip away at different undertakings and projects. Students can likewise peer audit other students' entries. Expertiza underpins accommodation crosswise over different record types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
* Improved the clarity of code by improving the variable and parameter names.&lt;br /&gt;
* Followed naming conventions throughout and renamed methods with inconsistent names including the calling methods.&lt;br /&gt;
* Rectified several unwanted if-else conditions in methods and optimized the code.&lt;br /&gt;
* Refactored all instance variables and removed unnecessarily defined variables.&lt;br /&gt;
* Removed certain unwanted flash messages that occur for some user actions.&lt;br /&gt;
* Included comments for functionalities throughout for better understanding.&lt;br /&gt;
&lt;br /&gt;
===About Sign-up sheet Controller===&lt;br /&gt;
Sign-up sheet controller contains all functions related to management of the signup sheet for an assignment function to add new topics to an assignment, edit properties of a particular topic, delete a topic, etc are included here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': Create method has an if-else condition determining if create or update should be called. Create method should not be responsible for calling update. Identify why the if-else condition exists. The if-else condition exists because the current implementation calls update if a signup sheet with the same name already exists. &lt;br /&gt;
* '''Solution''': Rectified this method by removing the call to update and flashing an error instead.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Update method has a plethora of instance variables defined before updating. These are not necessary (For e.g., look at update method of bookmarks_controller).&lt;br /&gt;
* '''Solution''': Refactored the variables not needed out.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 4''': The list method is too long and is sparsely commented.&lt;br /&gt;
* '''Solution''': Added comments.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# function to list all topics and bids to a participant&lt;br /&gt;
  def list&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    @@ -155,6 +156,8 @@ def list&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
&lt;br /&gt;
    # If the assignment supports bidding, add all the bids of an &lt;br /&gt;
    # individual or team to the list of signed topics&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
      signed_up_topics = []&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 5''': Add_signup_topics_staggered does not do anything.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #add_signup_topics_staggered calls add_signup_topics and does nothing else.&lt;br /&gt;
 def add_signup_topics_staggered&lt;br /&gt;
    add_signup_topics &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 6''': Several method names are renamed to be more intuitive.&lt;br /&gt;
* '''Solution''': load_add_signup_topics is renamed to get_assignment_data and ad_info is renamed to get_ad.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Contains links that let an admin or Instructor edit, delete, view enrolled/waitlisted members for each topic&lt;br /&gt;
  # Also contains links to delete topics and modify the deadlines for individual topics. Staggered means that different topics can have different deadlines.&lt;br /&gt;
  def add_signup_topics&lt;br /&gt;
    load_add_signup_topics(params[:id])&lt;br /&gt;
    get_assignment_data(params[:id])&lt;br /&gt;
    SignUpSheet.add_signup_topic(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @@ -109,7 +109,7 @@ def add_signup_topics_staggered&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_add_signup_topics(assignment_id)&lt;br /&gt;
  def get_assignment_data(assignment_id)&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
  @@ -374,7 +374,7 @@ def save_topic_deadlines&lt;br /&gt;
  # This method is called when a student click on the trumpet icon. So this is a bad method name. --Yang&lt;br /&gt;
  def show_team&lt;br /&gt;
    if !(assignment = Assignment.find(params[:assignment_id])).nil? and !(topic = SignUpTopic.find(params[:id])).nil?&lt;br /&gt;
      @results = ad_info(assignment.id, topic.id)&lt;br /&gt;
      @results = get_ad(assignment.id, topic.id)&lt;br /&gt;
      @results.each do |result|&lt;br /&gt;
        result.keys.each do |key|&lt;br /&gt;
          @current_team_name = result[key] if key.equal? :name&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 9''': Participants variable in load_add_signup_topics actually means teams that signed up for a topic.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    # to treat all assignments as team assignments&lt;br /&gt;
    # Though called participants, @participants are actually records in signed_up_teams table, which&lt;br /&gt;
    # is a mapping table between teams and topics (waitlisted recored are also counted)&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
    @teams = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 10''': Signup_as_instructor_action has if-else ladder.&lt;br /&gt;
* '''Solution''': It has been made more elegant using a helper function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
  def signup_student user&lt;br /&gt;
    if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
      flash[:success] = &amp;quot;You have successfully signed up the student for the topic!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = &amp;quot;The student has already signed up for a topic!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = &amp;quot;That student does not exist!&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    if !user.nil? and AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
      signup_student(user);&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = &amp;quot;You have successfully signed up the student for the topic!&amp;quot;&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = &amp;quot;The student has already signed up for a topic!&amp;quot;&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = &amp;quot;The student is not registered for the assignment!&amp;quot;&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
      flash[:error] = &amp;quot;The student is not registered for the assignment!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Checks if participant has permission to delete a topic, reports errors otherwise&lt;br /&gt;
  def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadline)&lt;br /&gt;
  def can_delete_topic? is_instructor, participant, assignment, drop_topic_deadline&lt;br /&gt;
    submission_error_message = &amp;quot;&amp;quot;&lt;br /&gt;
    deadline_error_message = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   @@ -237,7 +239,7 @@ def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadli&lt;br /&gt;
    else&lt;br /&gt;
      submission_error_message = &amp;quot;You have already submitted your work, so you are not allowed to drop your topic.&amp;quot;&lt;br /&gt;
      deadline_error_message = &amp;quot;You cannot drop your topic after the drop topic deadline!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
    if !participant.team.submitted_files.empty? or !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
   @@ -246,7 +248,7 @@ def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadli&lt;br /&gt;
      flash[:error] = deadline_error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
      return false&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   @@ -274,7 +276,6 @@ def delete_signup_as_instructor&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
&lt;br /&gt;
    if can_delete_topic?(true, participant, assignment, drop_topic_deadline)&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = &amp;quot;You have successfully dropped the student from the topic!&amp;quot;&lt;br /&gt;
   @@ -481,4 +482,4 @@ def ad_info(_assignment_id, topic_id)&lt;br /&gt;
  def delete_signup_for_topic(assignment_id, topic_id, user_id)&lt;br /&gt;
    SignUpTopic.reassign_topic(user_id, assignment_id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 11''': Delete_signup and delete_signup_as_instructor have much in common and violates the DRY principle. &lt;br /&gt;
* '''Solution''': Refactored them by moving the duplicate code to a helper function.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadline)&lt;br /&gt;
    submission_error_message = &amp;quot;&amp;quot;&lt;br /&gt;
    deadline_error_message = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if is_instructor?&lt;br /&gt;
      submission_error_message = &amp;quot;The student has already submitted their work, so you are not allowed to remove them&amp;quot;&lt;br /&gt;
      deadline_error_message = &amp;quot;You cannot drop a student after the drop topic deadline!&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      submission_error_message = &amp;quot;You have already submitted your work, so you are not allowed to drop your topic.&amp;quot;&lt;br /&gt;
      deadline_error_message = &amp;quot;You cannot drop your topic after the drop topic deadline!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if !participant.team.submitted_files.empty? or !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      return false&lt;br /&gt;
    elsif !drop_topic_deadline.nil? and Time.now &amp;gt; drop_topic_deadline.due_at&lt;br /&gt;
      flash[:error] = deadline_error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
      return false&lt;br /&gt;
&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # this function is used to delete a previous signup&lt;br /&gt;
  def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
@@ -235,13 +259,7 @@ def delete_signup&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? or !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = &amp;quot;You have already submitted your work, so you are not allowed to drop your topic.&amp;quot;&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? and Time.now &amp;gt; drop_topic_deadline.due_at&lt;br /&gt;
      flash[:error] = &amp;quot;You cannot drop your topic after the drop topic deadline!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
    if can_delete_topic?(false, participant, assignment, drop_topic_deadline)&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = &amp;quot;You have successfully dropped your topic!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
@@ -256,13 +274,8 @@ def delete_signup_as_instructor&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? or !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = &amp;quot;The student has already submitted their work, so you are not allowed to remove them.&amp;quot;&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? and Time.now &amp;gt; drop_topic_deadline.due_at&lt;br /&gt;
      flash[:error] = &amp;quot;You cannot drop a student after the drop topic deadline!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
&lt;br /&gt;
    if can_delete_topic?(true, participant, assignment, drop_topic_deadline)&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = &amp;quot;You have successfully dropped the student from the topic!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#https://github.com/expertiza/expertiza&lt;br /&gt;
#http://expertiza.ncsu.edu/ The live Expertiza website&lt;/div&gt;</summary>
		<author><name>Spadala</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122426</id>
		<title>E1908 signupsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122426"/>
		<updated>2019-03-26T01:35:01Z</updated>

		<summary type="html">&lt;p&gt;Spadala: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1908. Refactoring the Sign-up sheet Controller==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
[http://expertiza.ncsu.edu/Expertiza] is an open source project dependent on [http://rubyonrails.org/Ruby on Rails] structure. Expertiza enables the teacher to make new assignments and alter new or existing assignments. It additionally enables the educator to make a rundown of subjects the students can agree to accept. Students can shape groups in Expertiza to chip away at different undertakings and projects. Students can likewise peer audit other students' entries. Expertiza underpins accommodation crosswise over different record types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
* Improved the clarity of code by improving the variable and parameter names.&lt;br /&gt;
* Followed naming conventions throughout and renamed methods with inconsistent names including the calling methods.&lt;br /&gt;
* Rectified several unwanted if-else conditions in methods and optimized the code.&lt;br /&gt;
* Refactored all instance variables and removed unnecessarily defined variables.&lt;br /&gt;
* Removed certain unwanted flash messages that occur for some user actions.&lt;br /&gt;
* Included comments for functionalities throughout for better understanding.&lt;br /&gt;
&lt;br /&gt;
===About Sign-up sheet Controller===&lt;br /&gt;
Sign-up sheet controller contains all functions related to management of the signup sheet for an assignment function to add new topics to an assignment, edit properties of a particular topic, delete a topic, etc are included here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': Create method has an if-else condition determining if create or update should be called. Create method should not be responsible for calling update. Identify why the if-else condition exists. The if-else condition exists because the current implementation calls update if a signup sheet with the same name already exists. &lt;br /&gt;
* '''Solution''': Rectified this method by removing the call to update and flashing an error instead.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Update method has a plethora of instance variables defined before updating. These are not necessary (For e.g., look at update method of bookmarks_controller).&lt;br /&gt;
* '''Solution''': Refactored the variables not needed out.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 4''': The list method is too long and is sparsely commented.&lt;br /&gt;
* '''Solution''': Added comments.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# function to list all topics and bids to a participant&lt;br /&gt;
  def list&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    @@ -155,6 +156,8 @@ def list&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
&lt;br /&gt;
    # If the assignment supports bidding, add all the bids of an &lt;br /&gt;
    # individual or team to the list of signed topics&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
      signed_up_topics = []&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 5''': Add_signup_topics_staggered does not do anything.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #add_signup_topics_staggered calls add_signup_topics and does nothing else.&lt;br /&gt;
 def add_signup_topics_staggered&lt;br /&gt;
    add_signup_topics &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 6''': Several method names are renamed to be more intuitive.&lt;br /&gt;
* '''Solution''': load_add_signup_topics is renamed to get_assignment_data and ad_info is renamed to get_ad.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Contains links that let an admin or Instructor edit, delete, view enrolled/waitlisted members for each topic&lt;br /&gt;
  # Also contains links to delete topics and modify the deadlines for individual topics. Staggered means that different topics can have different deadlines.&lt;br /&gt;
  def add_signup_topics&lt;br /&gt;
    load_add_signup_topics(params[:id])&lt;br /&gt;
    get_assignment_data(params[:id])&lt;br /&gt;
    SignUpSheet.add_signup_topic(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @@ -109,7 +109,7 @@ def add_signup_topics_staggered&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_add_signup_topics(assignment_id)&lt;br /&gt;
  def get_assignment_data(assignment_id)&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
  @@ -374,7 +374,7 @@ def save_topic_deadlines&lt;br /&gt;
  # This method is called when a student click on the trumpet icon. So this is a bad method name. --Yang&lt;br /&gt;
  def show_team&lt;br /&gt;
    if !(assignment = Assignment.find(params[:assignment_id])).nil? and !(topic = SignUpTopic.find(params[:id])).nil?&lt;br /&gt;
      @results = ad_info(assignment.id, topic.id)&lt;br /&gt;
      @results = get_ad(assignment.id, topic.id)&lt;br /&gt;
      @results.each do |result|&lt;br /&gt;
        result.keys.each do |key|&lt;br /&gt;
          @current_team_name = result[key] if key.equal? :name&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 8''': Delete_signup and delete_signup_as_instructor have much in common and violates the DRY principle. &lt;br /&gt;
* '''Solution''': Refactored them by moving the duplicate code to a helper function.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 9''': Participants variable in load_add_signup_topics actually means teams that signed up for a topic.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    # to treat all assignments as team assignments&lt;br /&gt;
    # Though called participants, @participants are actually records in signed_up_teams table, which&lt;br /&gt;
    # is a mapping table between teams and topics (waitlisted recored are also counted)&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
    @teams = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 10''': Signup_as_instructor_action has if-else ladder.&lt;br /&gt;
* '''Solution''': It has been made more elegant using a helper function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
  def signup_student user&lt;br /&gt;
    if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
      flash[:success] = &amp;quot;You have successfully signed up the student for the topic!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = &amp;quot;The student has already signed up for a topic!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = &amp;quot;That student does not exist!&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    if !user.nil? and AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
      signup_student(user);&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = &amp;quot;You have successfully signed up the student for the topic!&amp;quot;&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = &amp;quot;The student has already signed up for a topic!&amp;quot;&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = &amp;quot;The student is not registered for the assignment!&amp;quot;&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
      flash[:error] = &amp;quot;The student is not registered for the assignment!&amp;quot;&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Checks if participant has permission to delete a topic, reports errors otherwise&lt;br /&gt;
  def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadline)&lt;br /&gt;
  def can_delete_topic? is_instructor, participant, assignment, drop_topic_deadline&lt;br /&gt;
    submission_error_message = &amp;quot;&amp;quot;&lt;br /&gt;
    deadline_error_message = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   @@ -237,7 +239,7 @@ def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadli&lt;br /&gt;
    else&lt;br /&gt;
      submission_error_message = &amp;quot;You have already submitted your work, so you are not allowed to drop your topic.&amp;quot;&lt;br /&gt;
      deadline_error_message = &amp;quot;You cannot drop your topic after the drop topic deadline!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
    if !participant.team.submitted_files.empty? or !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
   @@ -246,7 +248,7 @@ def can_delete_topic?(is_instructor?, participant, assignment, drop_topic_deadli&lt;br /&gt;
      flash[:error] = deadline_error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
      return false&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   @@ -274,7 +276,6 @@ def delete_signup_as_instructor&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
&lt;br /&gt;
    if can_delete_topic?(true, participant, assignment, drop_topic_deadline)&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = &amp;quot;You have successfully dropped the student from the topic!&amp;quot;&lt;br /&gt;
   @@ -481,4 +482,4 @@ def ad_info(_assignment_id, topic_id)&lt;br /&gt;
  def delete_signup_for_topic(assignment_id, topic_id, user_id)&lt;br /&gt;
    SignUpTopic.reassign_topic(user_id, assignment_id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#https://github.com/expertiza/expertiza&lt;br /&gt;
#http://expertiza.ncsu.edu/ The live Expertiza website&lt;/div&gt;</summary>
		<author><name>Spadala</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122419</id>
		<title>E1908 signupsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122419"/>
		<updated>2019-03-26T01:29:39Z</updated>

		<summary type="html">&lt;p&gt;Spadala: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1908. Refactoring the Sign-up sheet Controller==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
* Improved the clarity of code by improving the variable and parameter names.&lt;br /&gt;
* Followed naming conventions throughout and renamed methods with inconsistent names including the calling methods.&lt;br /&gt;
* Rectified several unwanted if-else conditions in methods and optimized the code.&lt;br /&gt;
* Refactored all instance variables and removed unnecessarily defined variables.&lt;br /&gt;
* Removed certain unwanted flash messages that occur for some user actions.&lt;br /&gt;
* Included comments for functionalities throughout for better understanding.&lt;br /&gt;
&lt;br /&gt;
===About Sign-up sheet Controller===&lt;br /&gt;
Sign-up sheet controller contains all functions related to management of the signup sheet for an assignment function to add new topics to an assignment, edit properties of a particular topic, delete a topic, etc are included here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': Create method has an if-else condition determining if create or update should be called. Create method should not be responsible for calling update. Identify why the if-else condition exists. The if-else condition exists because the current implementation calls update if a signup sheet with the same name already exists. &lt;br /&gt;
* '''Solution''': Rectified this method by removing the call to update and flashing an error instead.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Update method has a plethora of instance variables defined before updating. These are not necessary (For e.g., look at update method of bookmarks_controller).&lt;br /&gt;
* '''Solution''': Refactored the variables not needed out.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 4''': The list method is too long and is sparsely commented.&lt;br /&gt;
* '''Solution''': Added comments.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# function to list all topics and bids to a participant&lt;br /&gt;
  def list&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    @@ -155,6 +156,8 @@ def list&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
&lt;br /&gt;
    # If the assignment supports bidding, add all the bids of an &lt;br /&gt;
    # individual or team to the list of signed topics&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
      signed_up_topics = []&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 5''': Add_signup_topics_staggered does not do anything.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #add_signup_topics_staggered calls add_signup_topics and does nothing else.&lt;br /&gt;
 def add_signup_topics_staggered&lt;br /&gt;
    add_signup_topics &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 6''': Several method names are renamed to be more intuitive.&lt;br /&gt;
* '''Solution''': load_add_signup_topics is renamed to get_assignment_data and ad_info is renamed to get_ad.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Contains links that let an admin or Instructor edit, delete, view enrolled/waitlisted members for each topic&lt;br /&gt;
  # Also contains links to delete topics and modify the deadlines for individual topics. Staggered means that different topics can have different deadlines.&lt;br /&gt;
  def add_signup_topics&lt;br /&gt;
    load_add_signup_topics(params[:id])&lt;br /&gt;
    get_assignment_data(params[:id])&lt;br /&gt;
    SignUpSheet.add_signup_topic(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @@ -109,7 +109,7 @@ def add_signup_topics_staggered&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_add_signup_topics(assignment_id)&lt;br /&gt;
  def get_assignment_data(assignment_id)&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
  @@ -374,7 +374,7 @@ def save_topic_deadlines&lt;br /&gt;
  # This method is called when a student click on the trumpet icon. So this is a bad method name. --Yang&lt;br /&gt;
  def show_team&lt;br /&gt;
    if !(assignment = Assignment.find(params[:assignment_id])).nil? and !(topic = SignUpTopic.find(params[:id])).nil?&lt;br /&gt;
      @results = ad_info(assignment.id, topic.id)&lt;br /&gt;
      @results = get_ad(assignment.id, topic.id)&lt;br /&gt;
      @results.each do |result|&lt;br /&gt;
        result.keys.each do |key|&lt;br /&gt;
          @current_team_name = result[key] if key.equal? :name&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 7''': Signup_as_instructor_action has if-else ladder.&lt;br /&gt;
* '''Solution''': It has been made more elegant using a helper function.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 8''': Delete_signup and delete_signup_as_instructor have much in common and violates the DRY principle. &lt;br /&gt;
* '''Solution''': Refactored them by moving the duplicate code to a helper function.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 9''': Participants variable in load_add_signup_topics actually means teams that signed up for a topic.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    # to treat all assignments as team assignments&lt;br /&gt;
    # Though called participants, @participants are actually records in signed_up_teams table, which&lt;br /&gt;
    # is a mapping table between teams and topics (waitlisted recored are also counted)&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
    @teams = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#https://github.com/expertiza/expertiza&lt;br /&gt;
#http://expertiza.ncsu.edu/ The live Expertiza website&lt;/div&gt;</summary>
		<author><name>Spadala</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122414</id>
		<title>E1908 signupsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122414"/>
		<updated>2019-03-26T01:25:44Z</updated>

		<summary type="html">&lt;p&gt;Spadala: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1908. Refactoring the Sign-up sheet Controller==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
* Improved the clarity of code by improving the variable and parameter names.&lt;br /&gt;
* Followed naming conventions throughout and renamed methods with inconsistent names including the calling methods.&lt;br /&gt;
* Rectified several unwanted if-else conditions in methods and optimized the code.&lt;br /&gt;
* Refactored all instance variables and removed unnecessarily defined variables.&lt;br /&gt;
* Removed certain unwanted flash messages that occur for some user actions.&lt;br /&gt;
* Included comments for functionalities throughout for better understanding.&lt;br /&gt;
&lt;br /&gt;
===About Sign-up sheet Controller===&lt;br /&gt;
Sign-up sheet controller contains all functions related to management of the signup sheet for an assignment function to add new topics to an assignment, edit properties of a particular topic, delete a topic, etc are included here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': Create method has an if-else condition determining if create or update should be called. Create method should not be responsible for calling update. Identify why the if-else condition exists. The if-else condition exists because the current implementation calls update if a signup sheet with the same name already exists. &lt;br /&gt;
* '''Solution''': Rectified this method by removing the call to update and flashing an error instead.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Update method has a plethora of instance variables defined before updating. These are not necessary (For e.g., look at update method of bookmarks_controller).&lt;br /&gt;
* '''Solution''': Refactored the variables not needed out.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''': Several method names are renamed to be more intuitive.&lt;br /&gt;
* '''Solution''': load_add_signup_topics is renamed to get_assignment_data and ad_info is renamed to get_ad.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 4''': The list method is too long and is sparsely commented.&lt;br /&gt;
* '''Solution''': Added comments.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# function to list all topics and bids to a participant&lt;br /&gt;
  def list&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
@@ -155,6 +156,8 @@ def list&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
&lt;br /&gt;
    # If the assignment supports bidding, add all the bids of an &lt;br /&gt;
    # individual or team to the list of signed topics&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
      signed_up_topics = []&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 5''': Add_signup_topics_staggered does not do anything.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #add_signup_topics_staggered calls add_signup_topics and does nothing else.&lt;br /&gt;
 def add_signup_topics_staggered&lt;br /&gt;
    add_signup_topics &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 6''': Participants variable in load_add_signup_topics actually means teams that signed up for a topic.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 7''': Signup_as_instructor_action has if-else ladder.&lt;br /&gt;
* '''Solution''': It has been made more elegant using a helper function.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Problem 8''': Delete_signup and delete_signup_as_instructor have much in common and violates the DRY principle. &lt;br /&gt;
* '''Solution''': Refactored them by moving the duplicate code to a helper function.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#https://github.com/expertiza/expertiza&lt;br /&gt;
#http://expertiza.ncsu.edu/ The live Expertiza website&lt;/div&gt;</summary>
		<author><name>Spadala</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122391</id>
		<title>E1908 signupsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122391"/>
		<updated>2019-03-26T01:07:37Z</updated>

		<summary type="html">&lt;p&gt;Spadala: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1908. Refactoring the Sign-up sheet Controller==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
* Improved the clarity of code by improving the variable and parameter names.&lt;br /&gt;
* Followed naming conventions throughout and renamed methods with inconsistent names including the calling methods.&lt;br /&gt;
* Rectified several unwanted if-else conditions in methods and optimized the code.&lt;br /&gt;
* Refactored all instance variables and removed unnecessarily defined variables.&lt;br /&gt;
* Removed certain unwanted flash messages that occur for some user actions.&lt;br /&gt;
* Included comments for functionalities throughout for better understanding.&lt;br /&gt;
&lt;br /&gt;
===About Sign-up sheet Controller===&lt;br /&gt;
Sign-up sheet controller contains all functions related to management of the signup sheet for an assignment function to add new topics to an assignment, edit properties of a particular topic, delete a topic, etc are included here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': Create method has an if-else condition determining if create or update should be called. Create method should not be responsible for calling update.&lt;br /&gt;
:: Identify why the if-else condition exists. The if-else condition exists because the current implementation calls update if a signup sheet with the same name already exists. &lt;br /&gt;
* '''Solution''': Rectified this method by removing the call to update and flashing an error instead. &lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Update method has a plethora of instance variables defined before updating. These are not necessary (For e.g., look at update method of bookmarks_controller).&lt;br /&gt;
* '''Solution''': Refactored the variables not needed out.&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''': Several method names are renamed to be more intuitive.&lt;br /&gt;
* '''Solution''': load_add_signup_topics is renamed to get_assignment_data and ad_info is renamed to get_ad.&lt;br /&gt;
&lt;br /&gt;
* '''Problem 4''': The list method is too long and is sparsely commented.&lt;br /&gt;
* '''Solution''': Added comments.&lt;br /&gt;
&lt;br /&gt;
* '''Problem 5''': Participants variable in load_add_signup_topics actually means teams that signed up for a topic.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&lt;br /&gt;
* '''Problem 6''': Signup_as_instructor_action has if-else ladder.&lt;br /&gt;
* '''Solution''': It has been made more elegant using a helper function.&lt;br /&gt;
&lt;br /&gt;
* '''Problem 7''': Delete_signup and delete_signup_as_instructor have much in common and violates the DRY principle. &lt;br /&gt;
* '''Solution''': Refactored them by moving the duplicate code to a helper function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#https://github.com/expertiza/expertiza&lt;br /&gt;
#http://expertiza.ncsu.edu/ The live Expertiza website&lt;/div&gt;</summary>
		<author><name>Spadala</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122389</id>
		<title>E1908 signupsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122389"/>
		<updated>2019-03-26T01:05:34Z</updated>

		<summary type="html">&lt;p&gt;Spadala: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1908. Refactoring the Sign-up sheet Controller==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
* Improved the clarity of code by improving the variable and parameter names.&lt;br /&gt;
* Followed naming conventions throughout and renamed methods with inconsistent names including the calling methods.&lt;br /&gt;
* Rectified several unwanted if-else conditions in methods and optimized the code.&lt;br /&gt;
* Refactored all instance variables and removed unnecessarily defined variables.&lt;br /&gt;
* Removed certain unwanted flash messages that occur for some user actions.&lt;br /&gt;
* Included comments for functionalities throughout for better understanding.&lt;br /&gt;
&lt;br /&gt;
===About Sign-up sheet Controller===&lt;br /&gt;
Sign-up sheet controller contains all functions related to management of the signup sheet for an assignment function to add new topics to an assignment, edit properties of a particular topic, delete a topic, etc are included here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': Create method has an if-else condition determining if create or update should be called. Create method should not be responsible for calling update.&lt;br /&gt;
:: Identify why the if-else condition exists. The if-else condition exists because the current implementation calls update if a signup sheet with the same name already exists. &lt;br /&gt;
* '''Solution''': Rectified this method by removing the call to update and flashing an error instead. &lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Update method has a plethora of instance variables defined before updating. These are not necessary (For e.g., look at update method of bookmarks_controller).&lt;br /&gt;
* '''Solution''': Refactored the variables not needed out.&lt;br /&gt;
&lt;br /&gt;
* '''Problem 3''': Several method names are renamed to be more intuitive.&lt;br /&gt;
* '''Solution''': load_add_signup_topics is renamed to get_assignment_data and ad_info is renamed to get_ad.&lt;br /&gt;
&lt;br /&gt;
* '''Problem 4''': The list method is too long and is sparsely commented.&lt;br /&gt;
* '''Solution''': Added comments.&lt;br /&gt;
&lt;br /&gt;
* '''Problem 5''': Participants variable in load_add_signup_topics actually means teams that signed up for a topic.&lt;br /&gt;
* '''Solution''': Renamed participants variable to 'teams'.&lt;br /&gt;
&lt;br /&gt;
* '''Problem 6''': Signup_as_instructor_action has if-else ladder.&lt;br /&gt;
* '''Solution''': It has been made more elegant using a helper function.&lt;br /&gt;
&lt;br /&gt;
* '''Problem 7''': Delete_signup and delete_signup_as_instructor have much in common and violates the DRY principle. &lt;br /&gt;
* '''Solution''': Refactored them by moving the duplicate code to a helper function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza]&lt;br /&gt;
#[http://expertiza.ncsu.edu/ The live Expertiza website]&lt;/div&gt;</summary>
		<author><name>Spadala</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122324</id>
		<title>E1908 signupsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122324"/>
		<updated>2019-03-26T00:19:45Z</updated>

		<summary type="html">&lt;p&gt;Spadala: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1908. Refactoring the Sign-up sheet Controller==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
* Improved the clarity of code by improving the variable and parameter names.&lt;br /&gt;
* Followed naming conventions throughout and renamed methods with inconsistent names including the calling methods.&lt;br /&gt;
* Rectified several unwanted if-else conditions in methods and optimized the code.&lt;br /&gt;
* Refactored all instance variables and removed unnecessarily defined variables.&lt;br /&gt;
* Removed certain unwanted flash messages that occur for some user actions.&lt;br /&gt;
* Included comments for functionalities throughout for better understanding.&lt;br /&gt;
&lt;br /&gt;
===About Sign-up sheet Controller===&lt;br /&gt;
Sign-up sheet controller contains all functions related to management of the signup sheet for an assignment function to add new topics to an assignment, edit properties of a particular topic, delete a topic, etc are included here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': The search criteria created in the method paginate_list was difficult to comprehend.&lt;br /&gt;
::The code which builds the search criteria in the method paginate_list uses many string literals and conditions and is hardly intuitive. The programmer will have to spend some time to understand what the code is really doing.&lt;br /&gt;
* '''Solution''': The implementation has been changed. A student is not allowed to delete any versions now. Other types of users, for instance administrators, instructors and TAs are allowed to delete only the versions they are authorized to view.&lt;br /&gt;
* '''Problem 3''': The paginate method can be moved to a helper class.&lt;br /&gt;
::VersionsController is not the only component which require to paginate items. There are other components too. For instance, the UsersController has to paginate the list of users. Hence the Paginate method can be moved to a helper class which can be accessed by other components as well.&lt;br /&gt;
* '''Solution''': The filtering options has also been enhanced. The current user can now choose as part of the version search filter any user from a list of users if the current user is authorized to see the versions created by that user.&lt;br /&gt;
&lt;br /&gt;
===New Implementation===&lt;br /&gt;
*The method paginate_list has been split into 2 methods now. &lt;br /&gt;
** BuildSearchCriteria – as the name suggests the sole purpose of this method is to build a search criteria based on the input search filters when the current user initiates a search in versions.&lt;br /&gt;
** paginate_list – this method will call the paginate API.&lt;br /&gt;
:First the search criteria is built, then the criteria is applied to versions in the database to get all versions which matches the criteria and then the retrieved versions are paginated.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # pagination.&lt;br /&gt;
  def paginate_list(versions)&lt;br /&gt;
    paginate(versions, VERSIONS_PER_PAGE);&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def BuildSearchCriteria(id, user_id, item_type, event)&lt;br /&gt;
    # Set up the search criteria&lt;br /&gt;
    search_criteria = ''&lt;br /&gt;
    search_criteria = search_criteria + add_id_filter_if_valid(id).to_s&lt;br /&gt;
    if current_user_role? == 'Super-Administrator'&lt;br /&gt;
      search_criteria = search_criteria + add_user_filter_for_super_admin(user_id).to_s&lt;br /&gt;
    end&lt;br /&gt;
    search_criteria = search_criteria + add_user_filter&lt;br /&gt;
    search_criteria = search_criteria + add_version_type_filter(item_type).to_s&lt;br /&gt;
    search_criteria = search_criteria + add_event_filter(event).to_s&lt;br /&gt;
    search_criteria = search_criteria + add_date_time_filter&lt;br /&gt;
    search_criteria&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* The string literals and conditions in the method paginate_list were replaced with methods with intuitive names so that the programmer can understand the code more easily. We also removed an empty if clause and a redundant statement.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def add_id_filter_if_valid (id)&lt;br /&gt;
    &amp;quot;id = #{id} AND &amp;quot; if id &amp;amp;&amp;amp; id.to_i &amp;gt; 0&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_user_filter_for_super_admin (user_id)&lt;br /&gt;
    &amp;quot;whodunnit = #{user_id} AND &amp;quot; if user_id &amp;amp;&amp;amp; user_id.to_i &amp;gt; 0&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_user_filter&lt;br /&gt;
    &amp;quot;whodunnit = #{current_user.try(:id)} AND &amp;quot; if current_user.try(:id) &amp;amp;&amp;amp; current_user.try(:id).to_i &amp;gt; 0&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_event_filter (event)&lt;br /&gt;
    &amp;quot;event = '#{event}' AND &amp;quot; if event &amp;amp;&amp;amp; !(event.eql? 'Any')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_date_time_filter&lt;br /&gt;
    &amp;quot;created_at &amp;gt;= '#{time_to_string(params[:start_time])}' AND &amp;quot; +&lt;br /&gt;
        &amp;quot;created_at &amp;lt;= '#{time_to_string(params[:end_time])}'&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_version_type_filter (version_type)&lt;br /&gt;
    &amp;quot;item_type = '#{version_type}' AND &amp;quot; if version_type &amp;amp;&amp;amp; !(version_type.eql? 'Any')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* The paginate method has been moved to the helper class Pagination_Helper. This new method can be now reused by the different components like UsersController etc. The method receives two parameters, first the list to paginate and second the number of items to be displayed in a page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module PaginationHelper&lt;br /&gt;
&lt;br /&gt;
  def paginate (items, number_of_items_per_page)&lt;br /&gt;
    items.page(params[:page]).per_page(number_of_items_per_page)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
* Introduced a constant VERSIONS_PER_PAGE and assigned the value 25 to it. The pagination algorithm for VersionsController displays at most 25 versions in a page. The existing implementation uses the value 25 straight in the code and there are few problems associated with such an approach.&lt;br /&gt;
** It is not easy to understand what 25 is unless the programmer takes a close look at the code.&lt;br /&gt;
** In case if the value 25 is used at more than one places and in future a new requirement comes to show at most 30 versions in a page, all the values will have to be modified. It is not very DRY.&lt;br /&gt;
* The VersionsController was overriding AccessHelper - action_allowed? method to return true in all the cases. This was violating the whole purpose of the method action_allowed?. The purpose of this method is to determine whether the user who is triggering a CRUD operation is allowed to do so. So when the current user invokes a CRUD operation, the action_allowed? method is invoked first and if the method returns true the CRUD operation is triggered or else the user is intimated with a message and gracefully exited. Hence, when the action_allowed? method is overridden to return true always, it results in providing unauthorized access to certain users.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    true&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:With the new implementation the AccessHelper - action_allowed? method has been modified in such a way that unauthorized access is prevented. As per the new algorithm, 'new', 'create', 'edit', 'update' cannot be invoked by any user. These operations can be accessed only by ‘papertrail’ gem. Only an ‘Administrator’ or ‘Super-Administrator’ can call 'destroy_all' method. All the other methods are accessible to ‘Administrator’,  ‘Super-Administrator’, ‘Instructor’, ‘Teaching Assistant’ and ‘Student’.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    case params[:action]&lt;br /&gt;
    when 'new', 'create', 'edit', 'update'&lt;br /&gt;
    #Modifications can only be done by papertrail&lt;br /&gt;
      return false&lt;br /&gt;
    when 'destroy_all'&lt;br /&gt;
      ['Super-Administrator',&lt;br /&gt;
       'Administrator'].include? current_role_name&lt;br /&gt;
    else&lt;br /&gt;
      #Allow all others&lt;br /&gt;
      ['Super-Administrator',&lt;br /&gt;
       'Administrator',&lt;br /&gt;
       'Instructor',&lt;br /&gt;
       'Teaching Assistant',&lt;br /&gt;
       'Student'].include? current_role_name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for VersionsController. Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for VersionsController, to test all the modifications we have done to the code of the controller class. The tests use double and stub features of rspec-rails gem, to fake the log in by different users - Administrator, Instructor, Student etc. The tests can be executed &amp;quot;rpec spec&amp;quot; command as shown below.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user-expertiza $rspec spec&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
Finished in 5.39 seconds (files took 25.33 seconds to load)&lt;br /&gt;
66 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 19254&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Testing from UI===&lt;br /&gt;
Following are a few testcases with respectto our code changes that can be tried from UI:&lt;br /&gt;
1. To go to versions index page, type in the following url after logging in:&lt;br /&gt;
   http://152.46.16.81:3000/versions&lt;br /&gt;
&lt;br /&gt;
2. After logging in as student/instructor or admin : Try accessing the  new, create, edit, update actions. These actions are not allowed to any of the users.&lt;br /&gt;
   http://152.46.16.81:3000/versions/new&lt;br /&gt;
   This calls the new action. In the current production version of expertiza, it is unhandled and application gives a default 404 page.&lt;br /&gt;
&lt;br /&gt;
3. Another feature that can be tested from UI is Pagination. Try searching for a user's versions and see if the results are paginated or not. Search here:&lt;br /&gt;
   http://152.46.16.81:3000/versions/search&lt;br /&gt;
&lt;br /&gt;
4. Visit the same URL as step 3, you should see only the students under that instructor in the users dropdown.&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/WintersLt/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[http://expertiza.ncsu.edu/ The live Expertiza website]&lt;br /&gt;
#[http://bit.ly/myexpertiza  Demo link] &lt;br /&gt;
#[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza project documentation wiki]&lt;br /&gt;
#[https://relishapp.com/rspec Rspec Documentation]&lt;br /&gt;
#Clean Code: A handbook of agile software craftsmanship. Author: Robert C Martin&lt;/div&gt;</summary>
		<author><name>Spadala</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122305</id>
		<title>E1908 signupsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122305"/>
		<updated>2019-03-25T23:55:15Z</updated>

		<summary type="html">&lt;p&gt;Spadala: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1908. Refactoring the Sign-up sheet Controller==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
* Improved the clarity of code by improving the variable and parameter names.&lt;br /&gt;
* Followed naming conventions throughout and renamed methods with inconsistent names including the calling methods.&lt;br /&gt;
* Rectified several unwanted if-else conditions in methods and optimized the code.&lt;br /&gt;
* Refactored all instance variables and removed unnecessarily defined variables.&lt;br /&gt;
* &lt;br /&gt;
* Added missing CRUD methods to Versions Controller&lt;br /&gt;
* Added RSPEC test cases for testing changes done in Versions Controller&lt;br /&gt;
&lt;br /&gt;
===About Versions Controller===&lt;br /&gt;
This class manages different versions of reviews. If a reviewer reviews a submission, and after that, the author revises the submission, the next time the reviewer does a review (s)he will create a new version. Sometimes it’s necessary to find the current version of a review; sometimes it’s necessary to find all versions. Similarly, a user may want to delete the current version of a review, or all versions of a review. Pagination of versions helps the user to view a subset of versions at a time. Considering the huge number of versions in the system, it is very useful to have a pagination mechanism and a filtering mechanism which can be applied on the whole set of versions. The idea is to display the versions in an ordered, comprehensible and logical manner. In Expertiza the gem ‘will_paginate’ is used to achieve pagination.&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
* Any user irrespective of his/ her privileges can view all the versions.&lt;br /&gt;
::The versions which a particular user can view should be restricted based on the privileges of the user. For instance, only a user with Administrator privileges should be able to view all the versions in the system. However, that is not the case now. Every user can view all the versions irrespective of whether the user is a student or an administrator.&lt;br /&gt;
* Any user can delete any version&lt;br /&gt;
::The versions which a particular user can delete should be restricted based on the privileges of the user. For instance, a student should not be allowed to delete any version. According to the current implementation any user can delete any version in the system.&lt;br /&gt;
* Filtering of versions were restricted to the current user&lt;br /&gt;
::The filtering options on versions were restricted to the current user. Sometimes a user might want to view versions associated with other users. For instance, an instructor might want to view the list of versions created by a particular student. This is not possible with the current implementation.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': The method paginate_list is doing more than one thing.&lt;br /&gt;
::The method paginate_list was building a complex search criteria based on the input params, getting the list of versions from the Database matching this search criteria and then calling the Page API. All these tasks in a single method made it difficult to understand.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# For filtering the versions list with proper search and pagination.&lt;br /&gt;
  def paginate_list(id, user_id, item_type, event, datetime)&lt;br /&gt;
    # Set up the search criteria&lt;br /&gt;
    criteria = ''&lt;br /&gt;
    criteria = criteria + &amp;quot;id = #{id} AND &amp;quot; if id &amp;amp;&amp;amp; id.to_i &amp;gt; 0&lt;br /&gt;
    if current_user_role? == 'Super-Administrator'&lt;br /&gt;
      criteria = criteria + &amp;quot;whodunnit = #{user_id} AND &amp;quot; if user_id &amp;amp;&amp;amp; user_id.to_i &amp;gt; 0&lt;br /&gt;
    end&lt;br /&gt;
    criteria = criteria + &amp;quot;whodunnit = #{current_user.try(:id)} AND &amp;quot; if current_user.try(:id) &amp;amp;&amp;amp; current_user.try(:id).to_i &amp;gt; 0&lt;br /&gt;
    criteria = criteria + &amp;quot;item_type = '#{item_type}' AND &amp;quot; if item_type &amp;amp;&amp;amp; !(item_type.eql? 'Any')&lt;br /&gt;
    criteria = criteria + &amp;quot;event = '#{event}' AND &amp;quot; if event &amp;amp;&amp;amp; !(event.eql? 'Any')&lt;br /&gt;
    criteria = criteria + &amp;quot;created_at &amp;gt;= '#{time_to_string(params[:start_time])}' AND &amp;quot;&lt;br /&gt;
    criteria = criteria + &amp;quot;created_at &amp;lt;= '#{time_to_string(params[:end_time])}' AND &amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if current_role == 'Instructor' || current_role == 'Administrator'&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Remove the last ' AND '&lt;br /&gt;
    criteria = criteria[0..-5]&lt;br /&gt;
&lt;br /&gt;
    versions = Version.page(params[:page]).order('id').per_page(25).where(criteria)&lt;br /&gt;
    versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the versions which a user is allowed to see depends on the privileges of the user. The approach we have taken is as follows:&lt;br /&gt;
**An administrator can see all the versions&lt;br /&gt;
**An instructor can see all the versions created by him and other users who are in his course or are participants in the assignments he creates.&lt;br /&gt;
**A TA can see all the versions created by him and other users who are in the course for which he/ she assists.&lt;br /&gt;
**A Student can see all the versions created by him/ her.&lt;br /&gt;
* '''Problem 2''': The search criteria created in the method paginate_list was difficult to comprehend.&lt;br /&gt;
::The code which builds the search criteria in the method paginate_list uses many string literals and conditions and is hardly intuitive. The programmer will have to spend some time to understand what the code is really doing.&lt;br /&gt;
* '''Solution''': The implementation has been changed. A student is not allowed to delete any versions now. Other types of users, for instance administrators, instructors and TAs are allowed to delete only the versions they are authorized to view.&lt;br /&gt;
* '''Problem 3''': The paginate method can be moved to a helper class.&lt;br /&gt;
::VersionsController is not the only component which require to paginate items. There are other components too. For instance, the UsersController has to paginate the list of users. Hence the Paginate method can be moved to a helper class which can be accessed by other components as well.&lt;br /&gt;
* '''Solution''': The filtering options has also been enhanced. The current user can now choose as part of the version search filter any user from a list of users if the current user is authorized to see the versions created by that user.&lt;br /&gt;
&lt;br /&gt;
===New Implementation===&lt;br /&gt;
*The method paginate_list has been split into 2 methods now. &lt;br /&gt;
** BuildSearchCriteria – as the name suggests the sole purpose of this method is to build a search criteria based on the input search filters when the current user initiates a search in versions.&lt;br /&gt;
** paginate_list – this method will call the paginate API.&lt;br /&gt;
:First the search criteria is built, then the criteria is applied to versions in the database to get all versions which matches the criteria and then the retrieved versions are paginated.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # pagination.&lt;br /&gt;
  def paginate_list(versions)&lt;br /&gt;
    paginate(versions, VERSIONS_PER_PAGE);&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def BuildSearchCriteria(id, user_id, item_type, event)&lt;br /&gt;
    # Set up the search criteria&lt;br /&gt;
    search_criteria = ''&lt;br /&gt;
    search_criteria = search_criteria + add_id_filter_if_valid(id).to_s&lt;br /&gt;
    if current_user_role? == 'Super-Administrator'&lt;br /&gt;
      search_criteria = search_criteria + add_user_filter_for_super_admin(user_id).to_s&lt;br /&gt;
    end&lt;br /&gt;
    search_criteria = search_criteria + add_user_filter&lt;br /&gt;
    search_criteria = search_criteria + add_version_type_filter(item_type).to_s&lt;br /&gt;
    search_criteria = search_criteria + add_event_filter(event).to_s&lt;br /&gt;
    search_criteria = search_criteria + add_date_time_filter&lt;br /&gt;
    search_criteria&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* The string literals and conditions in the method paginate_list were replaced with methods with intuitive names so that the programmer can understand the code more easily. We also removed an empty if clause and a redundant statement.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def add_id_filter_if_valid (id)&lt;br /&gt;
    &amp;quot;id = #{id} AND &amp;quot; if id &amp;amp;&amp;amp; id.to_i &amp;gt; 0&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_user_filter_for_super_admin (user_id)&lt;br /&gt;
    &amp;quot;whodunnit = #{user_id} AND &amp;quot; if user_id &amp;amp;&amp;amp; user_id.to_i &amp;gt; 0&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_user_filter&lt;br /&gt;
    &amp;quot;whodunnit = #{current_user.try(:id)} AND &amp;quot; if current_user.try(:id) &amp;amp;&amp;amp; current_user.try(:id).to_i &amp;gt; 0&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_event_filter (event)&lt;br /&gt;
    &amp;quot;event = '#{event}' AND &amp;quot; if event &amp;amp;&amp;amp; !(event.eql? 'Any')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_date_time_filter&lt;br /&gt;
    &amp;quot;created_at &amp;gt;= '#{time_to_string(params[:start_time])}' AND &amp;quot; +&lt;br /&gt;
        &amp;quot;created_at &amp;lt;= '#{time_to_string(params[:end_time])}'&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_version_type_filter (version_type)&lt;br /&gt;
    &amp;quot;item_type = '#{version_type}' AND &amp;quot; if version_type &amp;amp;&amp;amp; !(version_type.eql? 'Any')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* The paginate method has been moved to the helper class Pagination_Helper. This new method can be now reused by the different components like UsersController etc. The method receives two parameters, first the list to paginate and second the number of items to be displayed in a page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module PaginationHelper&lt;br /&gt;
&lt;br /&gt;
  def paginate (items, number_of_items_per_page)&lt;br /&gt;
    items.page(params[:page]).per_page(number_of_items_per_page)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
* Introduced a constant VERSIONS_PER_PAGE and assigned the value 25 to it. The pagination algorithm for VersionsController displays at most 25 versions in a page. The existing implementation uses the value 25 straight in the code and there are few problems associated with such an approach.&lt;br /&gt;
** It is not easy to understand what 25 is unless the programmer takes a close look at the code.&lt;br /&gt;
** In case if the value 25 is used at more than one places and in future a new requirement comes to show at most 30 versions in a page, all the values will have to be modified. It is not very DRY.&lt;br /&gt;
* The VersionsController was overriding AccessHelper - action_allowed? method to return true in all the cases. This was violating the whole purpose of the method action_allowed?. The purpose of this method is to determine whether the user who is triggering a CRUD operation is allowed to do so. So when the current user invokes a CRUD operation, the action_allowed? method is invoked first and if the method returns true the CRUD operation is triggered or else the user is intimated with a message and gracefully exited. Hence, when the action_allowed? method is overridden to return true always, it results in providing unauthorized access to certain users.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    true&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:With the new implementation the AccessHelper - action_allowed? method has been modified in such a way that unauthorized access is prevented. As per the new algorithm, 'new', 'create', 'edit', 'update' cannot be invoked by any user. These operations can be accessed only by ‘papertrail’ gem. Only an ‘Administrator’ or ‘Super-Administrator’ can call 'destroy_all' method. All the other methods are accessible to ‘Administrator’,  ‘Super-Administrator’, ‘Instructor’, ‘Teaching Assistant’ and ‘Student’.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    case params[:action]&lt;br /&gt;
    when 'new', 'create', 'edit', 'update'&lt;br /&gt;
    #Modifications can only be done by papertrail&lt;br /&gt;
      return false&lt;br /&gt;
    when 'destroy_all'&lt;br /&gt;
      ['Super-Administrator',&lt;br /&gt;
       'Administrator'].include? current_role_name&lt;br /&gt;
    else&lt;br /&gt;
      #Allow all others&lt;br /&gt;
      ['Super-Administrator',&lt;br /&gt;
       'Administrator',&lt;br /&gt;
       'Instructor',&lt;br /&gt;
       'Teaching Assistant',&lt;br /&gt;
       'Student'].include? current_role_name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for VersionsController. Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for VersionsController, to test all the modifications we have done to the code of the controller class. The tests use double and stub features of rspec-rails gem, to fake the log in by different users - Administrator, Instructor, Student etc. The tests can be executed &amp;quot;rpec spec&amp;quot; command as shown below.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user-expertiza $rspec spec&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
Finished in 5.39 seconds (files took 25.33 seconds to load)&lt;br /&gt;
66 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 19254&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Testing from UI===&lt;br /&gt;
Following are a few testcases with respectto our code changes that can be tried from UI:&lt;br /&gt;
1. To go to versions index page, type in the following url after logging in:&lt;br /&gt;
   http://152.46.16.81:3000/versions&lt;br /&gt;
&lt;br /&gt;
2. After logging in as student/instructor or admin : Try accessing the  new, create, edit, update actions. These actions are not allowed to any of the users.&lt;br /&gt;
   http://152.46.16.81:3000/versions/new&lt;br /&gt;
   This calls the new action. In the current production version of expertiza, it is unhandled and application gives a default 404 page.&lt;br /&gt;
&lt;br /&gt;
3. Another feature that can be tested from UI is Pagination. Try searching for a user's versions and see if the results are paginated or not. Search here:&lt;br /&gt;
   http://152.46.16.81:3000/versions/search&lt;br /&gt;
&lt;br /&gt;
4. Visit the same URL as step 3, you should see only the students under that instructor in the users dropdown.&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/WintersLt/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[http://expertiza.ncsu.edu/ The live Expertiza website]&lt;br /&gt;
#[http://bit.ly/myexpertiza  Demo link] &lt;br /&gt;
#[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza project documentation wiki]&lt;br /&gt;
#[https://relishapp.com/rspec Rspec Documentation]&lt;br /&gt;
#Clean Code: A handbook of agile software craftsmanship. Author: Robert C Martin&lt;/div&gt;</summary>
		<author><name>Spadala</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122158</id>
		<title>E1908 signupsheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1908_signupsheet&amp;diff=122158"/>
		<updated>2019-03-25T19:27:11Z</updated>

		<summary type="html">&lt;p&gt;Spadala: Created page with &amp;quot;==E1908. Refactoring the Versions Controller==  This page provides a description of the Expertiza based OSS project.    __TOC__   ===About Expertiza===  [http://expertiza.ncsu.ed...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E1908. Refactoring the Versions Controller==&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===About Expertiza===&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open source project based on [http://rubyonrails.org/ Ruby on Rails] framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
* Improved the clarity of code by improving the variable and parameter names.&lt;br /&gt;
* Long character strings were taken and given appropriate names.&lt;br /&gt;
* Handled pagination by a separate helper module, which can be used by multiple controllers.&lt;br /&gt;
* Implemented action_allowed for access_control to prevent unauthorized access of methods.&lt;br /&gt;
* Prevented displaying of all versions for all users and tables when a user views the index page.&lt;br /&gt;
* Added missing CRUD methods to Versions Controller&lt;br /&gt;
* Added RSPEC testcases for testing changes done in Versions Controller&lt;br /&gt;
&lt;br /&gt;
===About Versions Controller===&lt;br /&gt;
This class manages different versions of reviews. If a reviewer reviews a submission, and after that, the author revises the submission, the next time the reviewer does a review (s)he will create a new version. Sometimes it’s necessary to find the current version of a review; sometimes it’s necessary to find all versions. Similarly, a user may want to delete the current version of a review, or all versions of a review. Pagination of versions helps the user to view a subset of versions at a time. Considering the huge number of versions in the system, it is very useful to have a pagination mechanism and a filtering mechanism which can be applied on the whole set of versions. The idea is to display the versions in an ordered, comprehensible and logical manner. In Expertiza the gem ‘will_paginate’ is used to achieve pagination.&lt;br /&gt;
&lt;br /&gt;
===Current Implementation===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
* Any user irrespective of his/ her privileges can view all the versions.&lt;br /&gt;
::The versions which a particular user can view should be restricted based on the privileges of the user. For instance, only a user with Administrator privileges should be able to view all the versions in the system. However, that is not the case now. Every user can view all the versions irrespective of whether the user is a student or an administrator.&lt;br /&gt;
* Any user can delete any version&lt;br /&gt;
::The versions which a particular user can delete should be restricted based on the privileges of the user. For instance, a student should not be allowed to delete any version. According to the current implementation any user can delete any version in the system.&lt;br /&gt;
* Filtering of versions were restricted to the current user&lt;br /&gt;
::The filtering options on versions were restricted to the current user. Sometimes a user might want to view versions associated with other users. For instance, an instructor might want to view the list of versions created by a particular student. This is not possible with the current implementation.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
* '''Problem 1''': The method paginate_list is doing more than one thing.&lt;br /&gt;
::The method paginate_list was building a complex search criteria based on the input params, getting the list of versions from the Database matching this search criteria and then calling the Page API. All these tasks in a single method made it difficult to understand.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# For filtering the versions list with proper search and pagination.&lt;br /&gt;
  def paginate_list(id, user_id, item_type, event, datetime)&lt;br /&gt;
    # Set up the search criteria&lt;br /&gt;
    criteria = ''&lt;br /&gt;
    criteria = criteria + &amp;quot;id = #{id} AND &amp;quot; if id &amp;amp;&amp;amp; id.to_i &amp;gt; 0&lt;br /&gt;
    if current_user_role? == 'Super-Administrator'&lt;br /&gt;
      criteria = criteria + &amp;quot;whodunnit = #{user_id} AND &amp;quot; if user_id &amp;amp;&amp;amp; user_id.to_i &amp;gt; 0&lt;br /&gt;
    end&lt;br /&gt;
    criteria = criteria + &amp;quot;whodunnit = #{current_user.try(:id)} AND &amp;quot; if current_user.try(:id) &amp;amp;&amp;amp; current_user.try(:id).to_i &amp;gt; 0&lt;br /&gt;
    criteria = criteria + &amp;quot;item_type = '#{item_type}' AND &amp;quot; if item_type &amp;amp;&amp;amp; !(item_type.eql? 'Any')&lt;br /&gt;
    criteria = criteria + &amp;quot;event = '#{event}' AND &amp;quot; if event &amp;amp;&amp;amp; !(event.eql? 'Any')&lt;br /&gt;
    criteria = criteria + &amp;quot;created_at &amp;gt;= '#{time_to_string(params[:start_time])}' AND &amp;quot;&lt;br /&gt;
    criteria = criteria + &amp;quot;created_at &amp;lt;= '#{time_to_string(params[:end_time])}' AND &amp;quot;&lt;br /&gt;
&lt;br /&gt;
    if current_role == 'Instructor' || current_role == 'Administrator'&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Remove the last ' AND '&lt;br /&gt;
    criteria = criteria[0..-5]&lt;br /&gt;
&lt;br /&gt;
    versions = Version.page(params[:page]).order('id').per_page(25).where(criteria)&lt;br /&gt;
    versions&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the versions which a user is allowed to see depends on the privileges of the user. The approach we have taken is as follows:&lt;br /&gt;
**An administrator can see all the versions&lt;br /&gt;
**An instructor can see all the versions created by him and other users who are in his course or are participants in the assignments he creates.&lt;br /&gt;
**A TA can see all the versions created by him and other users who are in the course for which he/ she assists.&lt;br /&gt;
**A Student can see all the versions created by him/ her.&lt;br /&gt;
* '''Problem 2''': The search criteria created in the method paginate_list was difficult to comprehend.&lt;br /&gt;
::The code which builds the search criteria in the method paginate_list uses many string literals and conditions and is hardly intuitive. The programmer will have to spend some time to understand what the code is really doing.&lt;br /&gt;
* '''Solution''': The implementation has been changed. A student is not allowed to delete any versions now. Other types of users, for instance administrators, instructors and TAs are allowed to delete only the versions they are authorized to view.&lt;br /&gt;
* '''Problem 3''': The paginate method can be moved to a helper class.&lt;br /&gt;
::VersionsController is not the only component which require to paginate items. There are other components too. For instance, the UsersController has to paginate the list of users. Hence the Paginate method can be moved to a helper class which can be accessed by other components as well.&lt;br /&gt;
* '''Solution''': The filtering options has also been enhanced. The current user can now choose as part of the version search filter any user from a list of users if the current user is authorized to see the versions created by that user.&lt;br /&gt;
&lt;br /&gt;
===New Implementation===&lt;br /&gt;
*The method paginate_list has been split into 2 methods now. &lt;br /&gt;
** BuildSearchCriteria – as the name suggests the sole purpose of this method is to build a search criteria based on the input search filters when the current user initiates a search in versions.&lt;br /&gt;
** paginate_list – this method will call the paginate API.&lt;br /&gt;
:First the search criteria is built, then the criteria is applied to versions in the database to get all versions which matches the criteria and then the retrieved versions are paginated.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # pagination.&lt;br /&gt;
  def paginate_list(versions)&lt;br /&gt;
    paginate(versions, VERSIONS_PER_PAGE);&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def BuildSearchCriteria(id, user_id, item_type, event)&lt;br /&gt;
    # Set up the search criteria&lt;br /&gt;
    search_criteria = ''&lt;br /&gt;
    search_criteria = search_criteria + add_id_filter_if_valid(id).to_s&lt;br /&gt;
    if current_user_role? == 'Super-Administrator'&lt;br /&gt;
      search_criteria = search_criteria + add_user_filter_for_super_admin(user_id).to_s&lt;br /&gt;
    end&lt;br /&gt;
    search_criteria = search_criteria + add_user_filter&lt;br /&gt;
    search_criteria = search_criteria + add_version_type_filter(item_type).to_s&lt;br /&gt;
    search_criteria = search_criteria + add_event_filter(event).to_s&lt;br /&gt;
    search_criteria = search_criteria + add_date_time_filter&lt;br /&gt;
    search_criteria&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* The string literals and conditions in the method paginate_list were replaced with methods with intuitive names so that the programmer can understand the code more easily. We also removed an empty if clause and a redundant statement.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def add_id_filter_if_valid (id)&lt;br /&gt;
    &amp;quot;id = #{id} AND &amp;quot; if id &amp;amp;&amp;amp; id.to_i &amp;gt; 0&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_user_filter_for_super_admin (user_id)&lt;br /&gt;
    &amp;quot;whodunnit = #{user_id} AND &amp;quot; if user_id &amp;amp;&amp;amp; user_id.to_i &amp;gt; 0&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_user_filter&lt;br /&gt;
    &amp;quot;whodunnit = #{current_user.try(:id)} AND &amp;quot; if current_user.try(:id) &amp;amp;&amp;amp; current_user.try(:id).to_i &amp;gt; 0&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_event_filter (event)&lt;br /&gt;
    &amp;quot;event = '#{event}' AND &amp;quot; if event &amp;amp;&amp;amp; !(event.eql? 'Any')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_date_time_filter&lt;br /&gt;
    &amp;quot;created_at &amp;gt;= '#{time_to_string(params[:start_time])}' AND &amp;quot; +&lt;br /&gt;
        &amp;quot;created_at &amp;lt;= '#{time_to_string(params[:end_time])}'&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add_version_type_filter (version_type)&lt;br /&gt;
    &amp;quot;item_type = '#{version_type}' AND &amp;quot; if version_type &amp;amp;&amp;amp; !(version_type.eql? 'Any')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* The paginate method has been moved to the helper class Pagination_Helper. This new method can be now reused by the different components like UsersController etc. The method receives two parameters, first the list to paginate and second the number of items to be displayed in a page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module PaginationHelper&lt;br /&gt;
&lt;br /&gt;
  def paginate (items, number_of_items_per_page)&lt;br /&gt;
    items.page(params[:page]).per_page(number_of_items_per_page)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Code improvements===&lt;br /&gt;
* Introduced a constant VERSIONS_PER_PAGE and assigned the value 25 to it. The pagination algorithm for VersionsController displays at most 25 versions in a page. The existing implementation uses the value 25 straight in the code and there are few problems associated with such an approach.&lt;br /&gt;
** It is not easy to understand what 25 is unless the programmer takes a close look at the code.&lt;br /&gt;
** In case if the value 25 is used at more than one places and in future a new requirement comes to show at most 30 versions in a page, all the values will have to be modified. It is not very DRY.&lt;br /&gt;
* The VersionsController was overriding AccessHelper - action_allowed? method to return true in all the cases. This was violating the whole purpose of the method action_allowed?. The purpose of this method is to determine whether the user who is triggering a CRUD operation is allowed to do so. So when the current user invokes a CRUD operation, the action_allowed? method is invoked first and if the method returns true the CRUD operation is triggered or else the user is intimated with a message and gracefully exited. Hence, when the action_allowed? method is overridden to return true always, it results in providing unauthorized access to certain users.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    true&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:With the new implementation the AccessHelper - action_allowed? method has been modified in such a way that unauthorized access is prevented. As per the new algorithm, 'new', 'create', 'edit', 'update' cannot be invoked by any user. These operations can be accessed only by ‘papertrail’ gem. Only an ‘Administrator’ or ‘Super-Administrator’ can call 'destroy_all' method. All the other methods are accessible to ‘Administrator’,  ‘Super-Administrator’, ‘Instructor’, ‘Teaching Assistant’ and ‘Student’.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    case params[:action]&lt;br /&gt;
    when 'new', 'create', 'edit', 'update'&lt;br /&gt;
    #Modifications can only be done by papertrail&lt;br /&gt;
      return false&lt;br /&gt;
    when 'destroy_all'&lt;br /&gt;
      ['Super-Administrator',&lt;br /&gt;
       'Administrator'].include? current_role_name&lt;br /&gt;
    else&lt;br /&gt;
      #Allow all others&lt;br /&gt;
      ['Super-Administrator',&lt;br /&gt;
       'Administrator',&lt;br /&gt;
       'Instructor',&lt;br /&gt;
       'Teaching Assistant',&lt;br /&gt;
       'Student'].include? current_role_name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Automated Testing using RSPEC===&lt;br /&gt;
The current version of expertiza did not have any test for VersionsController. Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for VersionsController, to test all the modifications we have done to the code of the controller class. The tests use double and stub features of rspec-rails gem, to fake the log in by different users - Administrator, Instructor, Student etc. The tests can be executed &amp;quot;rpec spec&amp;quot; command as shown below.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user-expertiza $rspec spec&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
Finished in 5.39 seconds (files took 25.33 seconds to load)&lt;br /&gt;
66 examples, 0 failures&lt;br /&gt;
&lt;br /&gt;
Randomized with seed 19254&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Testing from UI===&lt;br /&gt;
Following are a few testcases with respectto our code changes that can be tried from UI:&lt;br /&gt;
1. To go to versions index page, type in the following url after logging in:&lt;br /&gt;
   http://152.46.16.81:3000/versions&lt;br /&gt;
&lt;br /&gt;
2. After logging in as student/instructor or admin : Try accessing the  new, create, edit, update actions. These actions are not allowed to any of the users.&lt;br /&gt;
   http://152.46.16.81:3000/versions/new&lt;br /&gt;
   This calls the new action. In the current production version of expertiza, it is unhandled and application gives a default 404 page.&lt;br /&gt;
&lt;br /&gt;
3. Another feature that can be tested from UI is Pagination. Try searching for a user's versions and see if the results are paginated or not. Search here:&lt;br /&gt;
   http://152.46.16.81:3000/versions/search&lt;br /&gt;
&lt;br /&gt;
4. Visit the same URL as step 3, you should see only the students under that instructor in the users dropdown.&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
&lt;br /&gt;
#[https://github.com/expertiza/expertiza Expertiza on GitHub]&lt;br /&gt;
#[https://github.com/WintersLt/expertiza GitHub Project Repository Fork]&lt;br /&gt;
#[http://expertiza.ncsu.edu/ The live Expertiza website]&lt;br /&gt;
#[http://bit.ly/myexpertiza  Demo link] &lt;br /&gt;
#[http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza project documentation wiki]&lt;br /&gt;
#[https://relishapp.com/rspec Rspec Documentation]&lt;br /&gt;
#Clean Code: A handbook of agile software craftsmanship. Author: Robert C Martin&lt;/div&gt;</summary>
		<author><name>Spadala</name></author>
	</entry>
</feed>