<?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=Rlcoble</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=Rlcoble"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Rlcoble"/>
	<updated>2026-09-12T16:39:51Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_E1526&amp;diff=97079</id>
		<title>CSC/ECE 517 Spring 2015 E1526</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_E1526&amp;diff=97079"/>
		<updated>2015-05-04T04:14:13Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Code Details */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1526. Responsive web design for Expertiza&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Strategy =&lt;br /&gt;
&lt;br /&gt;
We analyzed the three Expertiza pages that we need to modify for this project, as well as all of their dependencies, and tried to identify all the tasks that we need to complete for this project. It became clear to us that a large majority of this project will be based on AngularJS, while the small fraction will be related to Bootstrap. Therefore, our strategy was to jumpstart this project by having all 4 team members work together on adding AngularJS to the Login page. Once the Login page was completed, we split in two groups. One group worked on implementing AngularJS on Manage-course page, while the other group worked on introducing AngularJS to Manage-User page.&lt;br /&gt;
The reasoning behind this strategy was that all of us working together on the Login page first allowed us to obtain some basic understanding of AngularJS and feel more comfortable using this impressively useful and powerful framework. We completed AngularJS constituents first by connecting some of the Rails controllers to AngularJS controllers and then, as a final step, we add Bootstrap. Our decision was based on the fact that Bootstrap does not require much work to be completed and it can be considered to be a pretty straight-forward element of the project.&lt;br /&gt;
&lt;br /&gt;
= Guide for future students =&lt;br /&gt;
1. Learn how to integrate AngularJS into Rails, using Rails original routing system.&lt;br /&gt;
&lt;br /&gt;
2. Learn AngularJS and Coffeescript, since the app.js is written in Coffeescript now.&lt;br /&gt;
&lt;br /&gt;
3. Learn Bootstrap, including the grid system, responsive design and etc.&lt;br /&gt;
&lt;br /&gt;
4. Read the code written by us, to know &lt;br /&gt;
&lt;br /&gt;
    a. how to pass data from Rails controller and view to AngularJS; &lt;br /&gt;
    b. how to pass data back to Rails view from AngularJS; &lt;br /&gt;
    c. how to convert JSON formatted data using in AngularJS to Rails hash and vice versa.&lt;br /&gt;
    d. how to present the data to Rails view&lt;br /&gt;
&lt;br /&gt;
= Integration =&lt;br /&gt;
This section represent the cornerstone of this project. It consciously explains how Angular and Rails can be integrated into a powerful system capable of providing solid control over both the backend and frontend development of your application.&lt;br /&gt;
&lt;br /&gt;
== Steps to interconnect Rails and AngularJS ==&lt;br /&gt;
&lt;br /&gt;
These guidelines assume that you have a Rails project in place and that you are intending to add AngularJS to it now. Please follow the steps bellow:&lt;br /&gt;
&lt;br /&gt;
1. In the Gemfile, ADD gem ‘bower-rails’ AND gem ‘angular-rails-templates’, then REMOVE ‘gem turbolinks'&lt;br /&gt;
&lt;br /&gt;
2. run &amp;lt;pre&amp;gt; bundle install&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Create a Bowerfile. It is used by AngularJS and it can be thought of as the Gemfile that Rails uses.&lt;br /&gt;
&lt;br /&gt;
4. In the Bowerfile, ADD asset ‘angular’ , asset ‘bootstrap-sass-official’, asset ‘angular-route’ AND asset ‘angular-boostrap’(for ui.bootstrap injection)&lt;br /&gt;
&lt;br /&gt;
5. run &amp;lt;pre&amp;gt; rake bower:install &amp;lt;/pre&amp;gt;. Bower installs dependencies in vender/assets/bower_components.&lt;br /&gt;
&lt;br /&gt;
6.  ADD the following content to the config/application.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 config.assets.paths &amp;lt;&amp;lt; Rails.root.join(&amp;quot;vendor&amp;quot;,&amp;quot;assets&amp;quot;,&amp;quot;bower_components&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
config.assets.paths &amp;lt;&amp;lt; Rails.root.join(&amp;quot;vendor&amp;quot;,&amp;quot;assets&amp;quot;,&amp;quot;bower_components&amp;quot;,&amp;quot;bootstrap-sass-official&amp;quot;,&amp;quot;assets&amp;quot;,&amp;quot;fonts&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
config.assets.precompile &amp;lt;&amp;lt; %r(.*.(?:eot|svg|ttf|woff|woff2)$) &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
7. REMOVE //= require turbolinks AND ADD &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//= require angular/angular&lt;br /&gt;
//= require angular-route/angular-route&lt;br /&gt;
//= require angular-rails-templates&lt;br /&gt;
//= require angular-bootstrap &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
to assets/javascripts/application.js&lt;br /&gt;
&lt;br /&gt;
8. Rename assets/stylesheets/application.css to assets/stylesheets/application.css.scss. &lt;br /&gt;
&lt;br /&gt;
9. ADD &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@import &amp;quot;bootstrap-sass-official/assets/stylesheets/bootstrap-sprockets&amp;quot;; and&lt;br /&gt;
@import &amp;quot;bootstrap-sass-official/assets/stylesheets/bootstrap&amp;quot;; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
to application.css.scss&lt;br /&gt;
&lt;br /&gt;
Since we are did not get to build a new website using AngularJS from scratch, it was a good idea to retain the routing system of Rails rather than implement it in AngularJS.&lt;br /&gt;
So, we added a new tag &amp;lt;code&amp;gt; div ng-app='MPApp'&amp;lt;/code&amp;gt; into the app/views/layout/application.html.erb to include all pages into the scope of our AngularJS app, named ‘MPApp’.&lt;br /&gt;
Then, for the home page app/views/content_pages/view.html.erb, we added a tag to make this page controlled by ‘testCtrl’, which was defined in app.coffee.&lt;br /&gt;
&lt;br /&gt;
== AngularJS's point of view ==&lt;br /&gt;
&lt;br /&gt;
1. Retrieving data from database&lt;br /&gt;
Because it is not appropriate to let AngularJS to directly fetch data from the MySQL database, the only way we could load data was through a Rails controller. For example, it is possible to do a http get/post request(GET /users/fetch_10_users) from AngularJS controller using $http injection or jQuery AJAX, which calls a new method ‘def fetch_10_users’ in the users_controller, which execute some database query via accessing methods in the user model, and returns json formatted data to the AngularJS controller. After getting the returning data, the AngularJS controller can present the data to the screen.&lt;br /&gt;
&lt;br /&gt;
2. Build custom directives&lt;br /&gt;
Instead of using the original Rails page, we decided to replace some forms and components using AngularJS directives, which enabled us to do some live modifications to the pages without loading.&lt;br /&gt;
&lt;br /&gt;
== Rails' point of view ==&lt;br /&gt;
The initial problem was how to provide entries from the database to AngularJS. We decided to create methods in Rails controller which will listen to the incoming AngulaJS and use a select statement to fetch a couple of entries from the database. These entries are then stored in a hash, converted to json and passed to AngularJS controller. AngularJS will then send another query request to Rails for the next set of entries. This strategy greatly reduces the loading time, making the time needed for representing the page kept at the minimum.&lt;br /&gt;
&lt;br /&gt;
=The specifics=&lt;br /&gt;
This section explains the very detailed actions and their results related to the 3 specific pages that were used to integrate AngularJS. Numerous snapshots are provided with the goal to make our approach very clear.&lt;br /&gt;
&lt;br /&gt;
== Login Page and Navigation Bar ==&lt;br /&gt;
Login procedure:&lt;br /&gt;
‘Login’ button clicked → auth_controller#login → auth_controller#after_login(user) → if user.role != ‘student’ → tree_display#drill → tree_display#list&amp;lt;br/&amp;gt;&lt;br /&gt;
If session[:menu] is defined, that is, when a user is logging in, the page will render the content of variable session[:menu].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;ul class=&amp;quot;nav navbar-nav&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;% if session[:menu] %&amp;gt;&lt;br /&gt;
       &amp;lt;%= render :partial =&amp;gt; 'menu_items/suckerfish',&lt;br /&gt;
          :locals =&amp;gt; { items: session[:menu].get_menu(0), level: 0 } %&amp;gt;&lt;br /&gt;
     &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul class=&amp;quot;nav navbar-nav&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;% if session[:menu] %&amp;gt;&lt;br /&gt;
      &amp;lt;%= render :partial =&amp;gt; 'menu_items/suckerfish',&lt;br /&gt;
         :locals =&amp;gt; { items: session[:menu].get_menu(0), level: 0 } %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
 &amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For each menu item in the nav bar, it is a dropdown menu now. For different level of dropdown menu, we apply different CSS style to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% level += 1 %&amp;gt;&lt;br /&gt;
&amp;lt;% items.each do |item_id|&lt;br /&gt;
  item = session[:menu].get_item(item_id)&lt;br /&gt;
  selected = session[:menu].selected?(item.id)&lt;br /&gt;
  long_name = item.name.split(/\W/).collect{|word| word.capitalize}.join(' ')&lt;br /&gt;
%&amp;gt;&lt;br /&gt;
&amp;lt;% if level == 1 %&amp;gt;&lt;br /&gt;
&amp;lt;li class=&amp;quot;dropdown first-level&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;% elsif level == 2 %&amp;gt;&lt;br /&gt;
&amp;lt;li class=&amp;quot;dropdown-submenu&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;% else %&amp;gt;&lt;br /&gt;
&amp;lt;li class=&amp;quot;dropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;a href=&amp;lt;%= URI.encode(&amp;quot;/menu/#{item.name}&amp;quot;) %&amp;gt;&lt;br /&gt;
  &amp;lt;%= if item.children&lt;br /&gt;
        ' class=&amp;quot;daddy&amp;quot;'&lt;br /&gt;
      end %&amp;gt;title='&amp;lt;%= long_name %&amp;gt;'&amp;gt;&amp;lt;%= item.label.html_safe %&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;% if item.children -%&amp;gt;&lt;br /&gt;
    &amp;lt;% if level == 1 %&amp;gt;&lt;br /&gt;
    &amp;lt;ul class=&amp;quot;dropdown-menu multi-level&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= render :partial =&amp;gt; 'menu_items/suckerfish', :locals =&amp;gt; {:items =&amp;gt; item.children, :level =&amp;gt; level} %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
    &amp;lt;ul class=&amp;quot;dropdown-menu&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;%= render :partial =&amp;gt; 'menu_items/suckerfish', :locals =&amp;gt; {:items =&amp;gt; item.children, :level =&amp;gt; level} %&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;% end -%&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;% end -%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Please also refer to app/assets/application.css.scss for further details.&lt;br /&gt;
&lt;br /&gt;
== Manage-course page ==&lt;br /&gt;
=== Design ===&lt;br /&gt;
After logging in, only the table frame is loaded into the page by rails. Then AngularJS takes over in the background and populate the content into the table. After all first-level content is populated into the table, in this case, all courses info belongs to the first level and their assignment is the second-level content.&lt;br /&gt;
&lt;br /&gt;
After all first level content is loaded into the table, the Angular controller starts to initialize POST request for second level content.&lt;br /&gt;
&lt;br /&gt;
In all, rendering the tree_display page is divided into 3 steps: &amp;lt;br&amp;gt;&lt;br /&gt;
1. render the table frame,  &amp;lt;br&amp;gt;&lt;br /&gt;
2. render the first level table content. &amp;lt;br&amp;gt;&lt;br /&gt;
3. fetch deeper level data. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the past, these 3 steps are done before rendering the page, which takes about 10-20 seconds. But now, it takes only 2-3 seconds to finish the first 2 steps, and 2 more seconds for the 3rd step.&lt;br /&gt;
&lt;br /&gt;
Moreover, the sorting and table record filtering is integrated into the table. No redirecting or re-rendering is needed for sorting or filtering, which was needed in the past.&lt;br /&gt;
&lt;br /&gt;
=== Code details ===&lt;br /&gt;
Pass Rails controller params to view in tree_display_controller#list&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
angularParams = {}&lt;br /&gt;
angularParams[:search] = @search&lt;br /&gt;
angularParams[:show] = @show&lt;br /&gt;
angularParams[:child_nodes] = @child_nodes&lt;br /&gt;
angularParams[:sortvar] = @sortvar&lt;br /&gt;
angularParams[:sortorder] = @sortorder&lt;br /&gt;
angularParams[:user_id] = session[:user].id&lt;br /&gt;
angularParams[:nodeType] = 'FolderNode'&lt;br /&gt;
@angularParamsJSON = angularParams.to_json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then the view passes to AngularJS&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div ng-controller='TreeCtrl'&amp;gt;&lt;br /&gt;
&amp;lt;div ng-init=&amp;quot;init('&amp;lt;%= @angularParamsJSON %&amp;gt;')&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AngularJS handles it, after all basic elements are loaded onto the page. Then AngularJS initializes a POST request for retrieving more data to populate the table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$scope.init = (value) -&amp;gt;&lt;br /&gt;
    $scope.angularParams = JSON.parse(value)&lt;br /&gt;
    $http.post('/tree_display/get_children_node_ng', {&lt;br /&gt;
      &amp;quot;angularParams&amp;quot;: $scope.angularParams&lt;br /&gt;
      })&lt;br /&gt;
    .success((data) -&amp;gt;&lt;br /&gt;
      $scope.tableContent = {}&lt;br /&gt;
      $scope.displayTableContent = {}&lt;br /&gt;
      $scope.lastLoadNum = {}&lt;br /&gt;
      $scope.typeList = []&lt;br /&gt;
      console.log data&lt;br /&gt;
      for nodeType, outerNode of data&lt;br /&gt;
        $scope.tableContent[nodeType] = []&lt;br /&gt;
        $scope.lastLoadNum[nodeType] = 0&lt;br /&gt;
        $scope.displayTableContent[nodeType] = []&lt;br /&gt;
        $scope.typeList.push nodeType&lt;br /&gt;
        # outerNode is the Assignments/Courses/Questionnaires&lt;br /&gt;
        for node in outerNode&lt;br /&gt;
          $scope.tableContent[nodeType].push node&lt;br /&gt;
          $scope.fetchCellContent(nodeType, node)&lt;br /&gt;
        $scope.getMoreContent(nodeType, 1)&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetch table cell content recursively and put them into a hash&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$scope.fetchCellContent = (nodeType, node) -&amp;gt;&lt;br /&gt;
    $scope.newParams = {}&lt;br /&gt;
    $scope.newParams[&amp;quot;sortvar&amp;quot;] = $scope.angularParams[&amp;quot;sortvar&amp;quot;]&lt;br /&gt;
    $scope.newParams[&amp;quot;sortorder&amp;quot;] = $scope.angularParams[&amp;quot;sortorder&amp;quot;]&lt;br /&gt;
    $scope.newParams[&amp;quot;search&amp;quot;] = $scope.angularParams[&amp;quot;search&amp;quot;]&lt;br /&gt;
    $scope.newParams[&amp;quot;show&amp;quot;] = $scope.angularParams[&amp;quot;show&amp;quot;]&lt;br /&gt;
    $scope.newParams[&amp;quot;user_id&amp;quot;] = $scope.angularParams[&amp;quot;user_id&amp;quot;]&lt;br /&gt;
    key = node.name + &amp;quot;|&amp;quot; + node.directory&lt;br /&gt;
    $scope.newParams[&amp;quot;key&amp;quot;] = key&lt;br /&gt;
    # console.log key&lt;br /&gt;
    if nodeType == 'Assignments'&lt;br /&gt;
      $scope.newParams[&amp;quot;nodeType&amp;quot;] = 'AssignmentNode'&lt;br /&gt;
    else if nodeType == 'Courses'&lt;br /&gt;
      $scope.newParams[&amp;quot;nodeType&amp;quot;] = 'CourseNode'&lt;br /&gt;
    else if nodeType == 'Questionnaires'&lt;br /&gt;
      $scope.newParams[&amp;quot;nodeType&amp;quot;] = 'FolderNode'&lt;br /&gt;
    else&lt;br /&gt;
      $scope.newParams[&amp;quot;nodeType&amp;quot;] = nodeType&lt;br /&gt;
&lt;br /&gt;
    $scope.newParams[&amp;quot;child_nodes&amp;quot;] = node.nodeinfo&lt;br /&gt;
    $http.post('/tree_display/get_children_node_2_ng', {&lt;br /&gt;
      &amp;quot;angularParams&amp;quot;: $scope.newParams&lt;br /&gt;
      })&lt;br /&gt;
    .success((data) -&amp;gt;&lt;br /&gt;
      if data.length &amp;gt; 0&lt;br /&gt;
        for newNode in data&lt;br /&gt;
          if not $scope.allData[newNode.key]&lt;br /&gt;
            $scope.allData[newNode.key] = []&lt;br /&gt;
          $scope.display[newNode.key] = false&lt;br /&gt;
          $scope.allData[newNode.key].push newNode&lt;br /&gt;
          $scope.fetchCellContent(newNode.type, newNode)&lt;br /&gt;
&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After all data is fetched, the Rails view is able to presenting them onto the page!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;tbody ng-repeat=&amp;quot;record in displayTableContent['Courses'] | filter:searchText | orderBy:predicate:reverse&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;tr ng-click=&amp;quot;showCellContent(record.name, record.directory)&amp;quot; class=&amp;quot;clickable-row&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;td&amp;gt;{{record.name}}&amp;lt;/td&amp;gt;&lt;br /&gt;
            &amp;lt;td&amp;gt;{{record.directory}}&amp;lt;/td&amp;gt;&lt;br /&gt;
            &amp;lt;td&amp;gt;{{record.creation_date}}&amp;lt;/td&amp;gt;&lt;br /&gt;
            &amp;lt;td&amp;gt;{{record.updated_date}}&amp;lt;/td&amp;gt;&lt;br /&gt;
            &amp;lt;td&amp;gt;&lt;br /&gt;
              &lt;br /&gt;
            &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          &amp;lt;/tr&amp;gt;&lt;br /&gt;
          &amp;lt;tr class=&amp;quot;no-cursor-tr no-color-tr&amp;quot; ng-if=&amp;quot;display[record.name+'|'+record.directory] &amp;amp;&amp;amp; allData[record.name+'|'+record.directory]&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;table class=&amp;quot;normal-table table table-bordered table-striped compact-table&amp;quot; ng-repeat=&amp;quot;cell in cellContent&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;tbody&amp;gt;&lt;br /&gt;
                &amp;lt;tr class=&amp;quot;no-cursor-tr no-color-tr&amp;quot;&amp;gt;&lt;br /&gt;
                  &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;: {{cell.name}}&amp;lt;/td&amp;gt;&lt;br /&gt;
                &amp;lt;/tr&amp;gt;&lt;br /&gt;
                &amp;lt;tr class=&amp;quot;no-cursor-tr no-color-tr&amp;quot;&amp;gt;&lt;br /&gt;
                  &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;Directory&amp;lt;/b&amp;gt;: {{cell.directory}}&amp;lt;/td&amp;gt;&lt;br /&gt;
                &amp;lt;/tr&amp;gt;&lt;br /&gt;
                &amp;lt;tr class=&amp;quot;no-cursor-tr no-color-tr&amp;quot;&amp;gt;&lt;br /&gt;
                  &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;Creation Date&amp;lt;/b&amp;gt;: {{cell.creation_date}}&amp;lt;/td&amp;gt;&lt;br /&gt;
                &amp;lt;/tr&amp;gt;&lt;br /&gt;
                &amp;lt;tr class=&amp;quot;no-cursor-tr no-color-tr&amp;quot;&amp;gt;&lt;br /&gt;
                  &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;Modified Date&amp;lt;/b&amp;gt;: {{cell.updated_date}}&amp;lt;/td&amp;gt;&lt;br /&gt;
                &amp;lt;/tr&amp;gt;&lt;br /&gt;
              &amp;lt;/tbody&amp;gt;&lt;br /&gt;
            &amp;lt;/table&amp;gt;&lt;br /&gt;
          &amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manage Users page ==&lt;br /&gt;
&lt;br /&gt;
===Design===&lt;br /&gt;
&lt;br /&gt;
Once logged in, choosing Manage/users option from the navbar, gets us routed to /users page which is defined in list.html.erb file. This file can be broken down to 5 constituents:&lt;br /&gt;
&lt;br /&gt;
1) Fetching Users &amp;lt;br&amp;gt;&lt;br /&gt;
2) Paginating Users &amp;lt;br&amp;gt;&lt;br /&gt;
3) Searching Users &amp;lt;br&amp;gt;&lt;br /&gt;
4) Showing Users &amp;lt;br&amp;gt;&lt;br /&gt;
5) Editing and Deleting Users &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Code Details===&lt;br /&gt;
&lt;br /&gt;
1) Fetching Users&lt;br /&gt;
Fetching users was challenging at first due to an extremely large number of user entries (total of 5300). Fetch of such large data produced a very long delay that was one of the major UX problems in legacy version of Expertiza. This problem has been solved with Angular by sending a post request that gets 300 users and then another post request which gets all the users. This approach provides a quick response and the first 300 users can be seen right away in the form of 3 pages (default set to 100 users per page). While the user is looking at the first couple of entries, the rest of the entries are fetched in the background. This allows for a fast response, full functionality as well as complete data.&lt;br /&gt;
&lt;br /&gt;
In app/assets/javascripts/app.coffee:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$scope.getUsers = (fn) -&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    $http.post('/users/get_users_ng', {&lt;br /&gt;
      'fetchNumber': fn&lt;br /&gt;
    })&lt;br /&gt;
    .success((receivedUsers) -&amp;gt;&lt;br /&gt;
      console.log receivedUsers&lt;br /&gt;
      for user in receivedUsers&lt;br /&gt;
        $scope.users.push user&lt;br /&gt;
        $scope.user_display[user.object.id] = false&lt;br /&gt;
        $scope.editProfileVisible[user.object.id] = false&lt;br /&gt;
&lt;br /&gt;
      $scope.fetchNumber+=1&lt;br /&gt;
      console.log $scope.users.length&lt;br /&gt;
      console.log $scope.listSize&lt;br /&gt;
&lt;br /&gt;
      if $scope.users.length &amp;lt; $scope.listSize&lt;br /&gt;
        $scope.getUsers($scope.fetchNumber)&lt;br /&gt;
      )&lt;br /&gt;
&lt;br /&gt;
  $scope.getUserListSize = () -&amp;gt;&lt;br /&gt;
    $http.get('/users/get_users_list_ng')&lt;br /&gt;
    .success((listSize) -&amp;gt;&lt;br /&gt;
      $scope.listSize = listSize&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This process is initiated by init() command shown bellow:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$scope.init = (value) -&amp;gt;&lt;br /&gt;
    $scope.user_display = {}&lt;br /&gt;
    $scope.editProfileVisible = {}&lt;br /&gt;
    if $scope.users.length == $scope.listSize&lt;br /&gt;
      return&lt;br /&gt;
    else if $scope.users.length == 0&lt;br /&gt;
      $scope.listSize = 0&lt;br /&gt;
      $scope.getUserListSize()&lt;br /&gt;
      $scope.fetchNumber = 0&lt;br /&gt;
    $scope.getUsers(($scope.fetchNumber))&lt;br /&gt;
    $scope.currentPage = 0&lt;br /&gt;
    $scope.pagination(50)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Paginating Users&lt;br /&gt;
&lt;br /&gt;
[[File:Pag_src.png]]&lt;br /&gt;
&lt;br /&gt;
In order to paginate users, a filter needs to be set in order to limit the number of users being shown:&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;tbody ng-repeat=&amp;quot;user in users | filter:search | startFrom:currentPage*pageSize | limitTo:pageSize&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;tr ng-click=&amp;quot;showUser(user.object.id)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.name}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.fullname}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.email}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.role}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.parent}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_review}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_submission}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_review_of_review}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.leaderboard_privacy}}&amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The startFrom:currentPage*pageSize portion of the filter calls the custom filter startFrom which simply splits the data to display based on the current page of pagination (currentPage), multiplied by the number of users to display (pageSize, which is set by the user selecting either All, 25, 50, 100, or 250).&lt;br /&gt;
&lt;br /&gt;
In app/assets/javascripts/app.coffee:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app.filter 'startFrom', -&amp;gt;&lt;br /&gt;
  (input, start) -&amp;gt;&lt;br /&gt;
    start = +start&lt;br /&gt;
    return input.slice start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The limitTo:pageSize is a built in angular filter that says to stop displaying users after pageSize of them have been displayed.&lt;br /&gt;
&lt;br /&gt;
The aforementioned pageSize is set by the user through a dropdown; This code tells the dropdown to set the default paginate value to 100 users per page, and upon an ng-change (user selecting a different value), the pagination method will be called in app.coffee, with the appropriate pageSize:&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;label&amp;gt;Paginate By: &lt;br /&gt;
    &amp;lt;select class=&amp;quot;form-control&amp;quot; ng-model=&amp;quot;paginate&amp;quot; ng-init=&amp;quot;paginate='50'&amp;quot; ng-change=&amp;quot;pagination(paginate)&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;0&amp;quot;&amp;gt;All&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;25&amp;quot;&amp;gt;25&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;50&amp;quot;&amp;gt;50&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;100&amp;quot;&amp;gt;100&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;250&amp;quot;&amp;gt;250&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;/label&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code is in app.coffee, and it posts the pageSize to the set_page_size method in the users_controller, and then sets various variable values based on the results:&lt;br /&gt;
&lt;br /&gt;
In app/assets/javascripts/app.coffee:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$scope.pagination = (ps) -&amp;gt;&lt;br /&gt;
    $http.post('/users/set_page_size', {&lt;br /&gt;
      'pageSize': ps&lt;br /&gt;
    })&lt;br /&gt;
    .success((value) -&amp;gt;&lt;br /&gt;
      $scope.pageSize = value[0]&lt;br /&gt;
      $scope.div = value[1]&lt;br /&gt;
      $scope.totalSize = value[2]&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code is in users_controller and it takes in the user defined pageSize variable and then determines how many pages are required to divide the data into based off of the pageSize, then returns that variable, plus others:&lt;br /&gt;
&lt;br /&gt;
In app/controllers/user_controller:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def set_page_size&lt;br /&gt;
    ps = params[:pageSize].to_i&lt;br /&gt;
    user = session[:user]&lt;br /&gt;
    role = Role.find(user.role_id)&lt;br /&gt;
    all_users = User.order('name').where( ['role_id in (?) or id = ?', role.get_available_roles, user.id])&lt;br /&gt;
    users_length = all_users.length&lt;br /&gt;
    if ps == 0&lt;br /&gt;
      pageSize = users_length&lt;br /&gt;
    else&lt;br /&gt;
      pageSize = ps&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    div = (users_length/pageSize.to_f).ceil&lt;br /&gt;
    &lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      format.html {render json: [pageSize, div, users_length]}&lt;br /&gt;
    end&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the number of pages and pageSize has been set, those numbers are then used to show the current and remaining pages to go along with the previous and next buttons:&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;paginate-button&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;button class=&amp;quot;glyphicon glyphicon-chevron-left&amp;quot; ng-disabled=&amp;quot;currentPage == 0&amp;quot; ng-click=&amp;quot;currentPage=currentPage-1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
  {{currentPage+1}}/{{div}}&lt;br /&gt;
  &amp;lt;button class=&amp;quot;glyphicon glyphicon-chevron-right&amp;quot; ng-disabled=&amp;quot;currentPage &amp;gt;= totalSize/pageSize - 1&amp;quot; ng-click=&amp;quot;currentPage=currentPage+1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Searching Users&lt;br /&gt;
&lt;br /&gt;
[[File:Pag_src.png]]&lt;br /&gt;
&lt;br /&gt;
In order to search users, a filter also needs to be set in order to limit the number of users being shown:&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;tbody ng-repeat=&amp;quot;user in users | filter:search | startFrom:currentPage*pageSize | limitTo:pageSize&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;tr ng-click=&amp;quot;showUser(user.object.id)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.name}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.fullname}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.email}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.role}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.parent}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_review}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_submission}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_review_of_review}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.leaderboard_privacy}}&amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The filter:search portion of this code simply applies the following filter criteria; the type of search is determined a dropdown (either search by any field, name, fullname, or email fields). Based on the dropdown selection, the correct search box will be shown, once that search box is show, the search criteria is set to correspond to the type of search specified by the dropdown:&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;pull-right form-group&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;form-inline&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label&amp;gt;Search By: &lt;br /&gt;
    &amp;lt;select class=&amp;quot;form-control&amp;quot; ng-model=&amp;quot;searchtype&amp;quot; ng-init=&amp;quot;searchtype='any'&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;any&amp;quot;&amp;gt;Any&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;name&amp;quot;&amp;gt;Name&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;fullname&amp;quot;&amp;gt;Full Name&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;email&amp;quot;&amp;gt;Email&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
  &amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input class=&amp;quot;form-control&amp;quot; ng-hide=&amp;quot;searchtype != 'any'&amp;quot; ng-model=&amp;quot;search.object.$&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input class=&amp;quot;form-control&amp;quot; ng-hide=&amp;quot;searchtype != 'name'&amp;quot; ng-model=&amp;quot;search.object.name&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input class=&amp;quot;form-control&amp;quot; ng-hide=&amp;quot;searchtype != 'fullname'&amp;quot; ng-model=&amp;quot;search.object.fullname&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input class=&amp;quot;form-control&amp;quot; ng-hide=&amp;quot;searchtype != 'email'&amp;quot; ng-model=&amp;quot;search.object.email&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Showing Users&lt;br /&gt;
Clicking on each user name in the table of users uncovers a template that shows the information about that specific user. This is accomplished in a very simple way by setting the profileVisible flag to true. The information about that specific user is extracted from displayedUser object provided by showUser() method from UsersPageCtrl controller in app.coffee file.&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div ng-if=&amp;quot;profileVisible == true&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;&amp;lt;b&amp;gt;User: {{displayedUser.object.name}}&amp;lt;/b&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;h3&amp;gt;&amp;lt;b&amp;gt;Full Name: &amp;lt;/b&amp;gt;{{displayedUser.object.fullname}}&amp;lt;/h3&amp;gt;&lt;br /&gt;
  &amp;lt;h3&amp;gt;&amp;lt;b&amp;gt;Email Address: &amp;lt;/b&amp;gt;{{displayedUser.object.email}}&amp;lt;/h3&amp;gt;&lt;br /&gt;
  &amp;lt;h3&amp;gt;&amp;lt;b&amp;gt;Role: &amp;lt;/b&amp;gt;{{displayedUser.role}}&amp;lt;/h3&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;button ng-click=&amp;quot;showTable(true)&amp;quot; type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-primary&amp;quot;&amp;gt;Back&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;button ng-click=&amp;quot;editUser()&amp;quot; type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-success&amp;quot;&amp;gt;Edit&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;button ng-click=&amp;quot;deleteUser()&amp;quot; type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-danger&amp;quot;&amp;gt;Delete&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In app/assets/javascripts/app.coffee:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $scope.showUser = (user_id) -&amp;gt;&lt;br /&gt;
    $scope.user_display[user_id] = !$scope.user_display[user_id]&lt;br /&gt;
    $scope.editProfileVisible[user_id] = false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
5) Editing and Deleting Users&lt;br /&gt;
&lt;br /&gt;
Editing Users is implemented in a similar way as showing users. The template contains ng-if statement which allows us to display edit page for each user. editUser() method from UsersPageCtrl controller specified in app.coffee displays information of the displayedUser but only after the Save button is clicked it saves the information from displayedUsers into updatedUser variable. POST request with :id parameter is then sent to update method in users_controller of Rails, which then updates this user information in the database.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $scope.editUser = (user) -&amp;gt;&lt;br /&gt;
    # $scope.showUser(false)&lt;br /&gt;
    $scope.editProfileVisible[user.object.id] = !$scope.editProfileVisible[user.object.id]&lt;br /&gt;
    $scope.updatedUser = user&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Pag_src.png&amp;diff=97078</id>
		<title>File:Pag src.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Pag_src.png&amp;diff=97078"/>
		<updated>2015-05-04T04:11:58Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_E1526&amp;diff=97077</id>
		<title>CSC/ECE 517 Spring 2015 E1526</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2015_E1526&amp;diff=97077"/>
		<updated>2015-05-04T04:11:28Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Code Details */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;E1526. Responsive web design for Expertiza&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Strategy =&lt;br /&gt;
&lt;br /&gt;
We analyzed the three Expertiza pages that we need to modify for this project, as well as all of their dependencies, and tried to identify all the tasks that we need to complete for this project. It became clear to us that a large majority of this project will be based on AngularJS, while the small fraction will be related to Bootstrap. Therefore, our strategy was to jumpstart this project by having all 4 team members work together on adding AngularJS to the Login page. Once the Login page was completed, we split in two groups. One group worked on implementing AngularJS on Manage-course page, while the other group worked on introducing AngularJS to Manage-User page.&lt;br /&gt;
The reasoning behind this strategy was that all of us working together on the Login page first allowed us to obtain some basic understanding of AngularJS and feel more comfortable using this impressively useful and powerful framework. We completed AngularJS constituents first by connecting some of the Rails controllers to AngularJS controllers and then, as a final step, we add Bootstrap. Our decision was based on the fact that Bootstrap does not require much work to be completed and it can be considered to be a pretty straight-forward element of the project.&lt;br /&gt;
&lt;br /&gt;
= Guide for future students =&lt;br /&gt;
1. Learn how to integrate AngularJS into Rails, using Rails original routing system.&lt;br /&gt;
&lt;br /&gt;
2. Learn AngularJS and Coffeescript, since the app.js is written in Coffeescript now.&lt;br /&gt;
&lt;br /&gt;
3. Learn Bootstrap, including the grid system, responsive design and etc.&lt;br /&gt;
&lt;br /&gt;
4. Read the code written by us, to know &lt;br /&gt;
&lt;br /&gt;
    a. how to pass data from Rails controller and view to AngularJS; &lt;br /&gt;
    b. how to pass data back to Rails view from AngularJS; &lt;br /&gt;
    c. how to convert JSON formatted data using in AngularJS to Rails hash and vice versa.&lt;br /&gt;
    d. how to present the data to Rails view&lt;br /&gt;
&lt;br /&gt;
= Integration =&lt;br /&gt;
This section represent the cornerstone of this project. It consciously explains how Angular and Rails can be integrated into a powerful system capable of providing solid control over both the backend and frontend development of your application.&lt;br /&gt;
&lt;br /&gt;
== Steps to interconnect Rails and AngularJS ==&lt;br /&gt;
&lt;br /&gt;
These guidelines assume that you have a Rails project in place and that you are intending to add AngularJS to it now. Please follow the steps bellow:&lt;br /&gt;
&lt;br /&gt;
1. In the Gemfile, ADD gem ‘bower-rails’ AND gem ‘angular-rails-templates’, then REMOVE ‘gem turbolinks'&lt;br /&gt;
&lt;br /&gt;
2. run &amp;lt;pre&amp;gt; bundle install&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Create a Bowerfile. It is used by AngularJS and it can be thought of as the Gemfile that Rails uses.&lt;br /&gt;
&lt;br /&gt;
4. In the Bowerfile, ADD asset ‘angular’ , asset ‘bootstrap-sass-official’, asset ‘angular-route’ AND asset ‘angular-boostrap’(for ui.bootstrap injection)&lt;br /&gt;
&lt;br /&gt;
5. run &amp;lt;pre&amp;gt; rake bower:install &amp;lt;/pre&amp;gt;. Bower installs dependencies in vender/assets/bower_components.&lt;br /&gt;
&lt;br /&gt;
6.  ADD the following content to the config/application.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 config.assets.paths &amp;lt;&amp;lt; Rails.root.join(&amp;quot;vendor&amp;quot;,&amp;quot;assets&amp;quot;,&amp;quot;bower_components&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
config.assets.paths &amp;lt;&amp;lt; Rails.root.join(&amp;quot;vendor&amp;quot;,&amp;quot;assets&amp;quot;,&amp;quot;bower_components&amp;quot;,&amp;quot;bootstrap-sass-official&amp;quot;,&amp;quot;assets&amp;quot;,&amp;quot;fonts&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
config.assets.precompile &amp;lt;&amp;lt; %r(.*.(?:eot|svg|ttf|woff|woff2)$) &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
7. REMOVE //= require turbolinks AND ADD &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//= require angular/angular&lt;br /&gt;
//= require angular-route/angular-route&lt;br /&gt;
//= require angular-rails-templates&lt;br /&gt;
//= require angular-bootstrap &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
to assets/javascripts/application.js&lt;br /&gt;
&lt;br /&gt;
8. Rename assets/stylesheets/application.css to assets/stylesheets/application.css.scss. &lt;br /&gt;
&lt;br /&gt;
9. ADD &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@import &amp;quot;bootstrap-sass-official/assets/stylesheets/bootstrap-sprockets&amp;quot;; and&lt;br /&gt;
@import &amp;quot;bootstrap-sass-official/assets/stylesheets/bootstrap&amp;quot;; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
to application.css.scss&lt;br /&gt;
&lt;br /&gt;
Since we are did not get to build a new website using AngularJS from scratch, it was a good idea to retain the routing system of Rails rather than implement it in AngularJS.&lt;br /&gt;
So, we added a new tag &amp;lt;code&amp;gt; div ng-app='MPApp'&amp;lt;/code&amp;gt; into the app/views/layout/application.html.erb to include all pages into the scope of our AngularJS app, named ‘MPApp’.&lt;br /&gt;
Then, for the home page app/views/content_pages/view.html.erb, we added a tag to make this page controlled by ‘testCtrl’, which was defined in app.coffee.&lt;br /&gt;
&lt;br /&gt;
== AngularJS's point of view ==&lt;br /&gt;
&lt;br /&gt;
1. Retrieving data from database&lt;br /&gt;
Because it is not appropriate to let AngularJS to directly fetch data from the MySQL database, the only way we could load data was through a Rails controller. For example, it is possible to do a http get/post request(GET /users/fetch_10_users) from AngularJS controller using $http injection or jQuery AJAX, which calls a new method ‘def fetch_10_users’ in the users_controller, which execute some database query via accessing methods in the user model, and returns json formatted data to the AngularJS controller. After getting the returning data, the AngularJS controller can present the data to the screen.&lt;br /&gt;
&lt;br /&gt;
2. Build custom directives&lt;br /&gt;
Instead of using the original Rails page, we decided to replace some forms and components using AngularJS directives, which enabled us to do some live modifications to the pages without loading.&lt;br /&gt;
&lt;br /&gt;
== Rails' point of view ==&lt;br /&gt;
The initial problem was how to provide entries from the database to AngularJS. We decided to create methods in Rails controller which will listen to the incoming AngulaJS and use a select statement to fetch a couple of entries from the database. These entries are then stored in a hash, converted to json and passed to AngularJS controller. AngularJS will then send another query request to Rails for the next set of entries. This strategy greatly reduces the loading time, making the time needed for representing the page kept at the minimum.&lt;br /&gt;
&lt;br /&gt;
=The specifics=&lt;br /&gt;
This section explains the very detailed actions and their results related to the 3 specific pages that were used to integrate AngularJS. Numerous snapshots are provided with the goal to make our approach very clear.&lt;br /&gt;
&lt;br /&gt;
== Login Page and Navigation Bar ==&lt;br /&gt;
Login procedure:&lt;br /&gt;
‘Login’ button clicked → auth_controller#login → auth_controller#after_login(user) → if user.role != ‘student’ → tree_display#drill → tree_display#list&amp;lt;br/&amp;gt;&lt;br /&gt;
If session[:menu] is defined, that is, when a user is logging in, the page will render the content of variable session[:menu].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;ul class=&amp;quot;nav navbar-nav&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;% if session[:menu] %&amp;gt;&lt;br /&gt;
       &amp;lt;%= render :partial =&amp;gt; 'menu_items/suckerfish',&lt;br /&gt;
          :locals =&amp;gt; { items: session[:menu].get_menu(0), level: 0 } %&amp;gt;&lt;br /&gt;
     &amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul class=&amp;quot;nav navbar-nav&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;% if session[:menu] %&amp;gt;&lt;br /&gt;
      &amp;lt;%= render :partial =&amp;gt; 'menu_items/suckerfish',&lt;br /&gt;
         :locals =&amp;gt; { items: session[:menu].get_menu(0), level: 0 } %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
 &amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For each menu item in the nav bar, it is a dropdown menu now. For different level of dropdown menu, we apply different CSS style to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% level += 1 %&amp;gt;&lt;br /&gt;
&amp;lt;% items.each do |item_id|&lt;br /&gt;
  item = session[:menu].get_item(item_id)&lt;br /&gt;
  selected = session[:menu].selected?(item.id)&lt;br /&gt;
  long_name = item.name.split(/\W/).collect{|word| word.capitalize}.join(' ')&lt;br /&gt;
%&amp;gt;&lt;br /&gt;
&amp;lt;% if level == 1 %&amp;gt;&lt;br /&gt;
&amp;lt;li class=&amp;quot;dropdown first-level&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;% elsif level == 2 %&amp;gt;&lt;br /&gt;
&amp;lt;li class=&amp;quot;dropdown-submenu&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;% else %&amp;gt;&lt;br /&gt;
&amp;lt;li class=&amp;quot;dropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;a href=&amp;lt;%= URI.encode(&amp;quot;/menu/#{item.name}&amp;quot;) %&amp;gt;&lt;br /&gt;
  &amp;lt;%= if item.children&lt;br /&gt;
        ' class=&amp;quot;daddy&amp;quot;'&lt;br /&gt;
      end %&amp;gt;title='&amp;lt;%= long_name %&amp;gt;'&amp;gt;&amp;lt;%= item.label.html_safe %&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
    &amp;lt;% if item.children -%&amp;gt;&lt;br /&gt;
    &amp;lt;% if level == 1 %&amp;gt;&lt;br /&gt;
    &amp;lt;ul class=&amp;quot;dropdown-menu multi-level&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= render :partial =&amp;gt; 'menu_items/suckerfish', :locals =&amp;gt; {:items =&amp;gt; item.children, :level =&amp;gt; level} %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;% else %&amp;gt;&lt;br /&gt;
    &amp;lt;ul class=&amp;quot;dropdown-menu&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;%= render :partial =&amp;gt; 'menu_items/suckerfish', :locals =&amp;gt; {:items =&amp;gt; item.children, :level =&amp;gt; level} %&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;% end -%&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;% end -%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Please also refer to app/assets/application.css.scss for further details.&lt;br /&gt;
&lt;br /&gt;
== Manage-course page ==&lt;br /&gt;
=== Design ===&lt;br /&gt;
After logging in, only the table frame is loaded into the page by rails. Then AngularJS takes over in the background and populate the content into the table. After all first-level content is populated into the table, in this case, all courses info belongs to the first level and their assignment is the second-level content.&lt;br /&gt;
&lt;br /&gt;
After all first level content is loaded into the table, the Angular controller starts to initialize POST request for second level content.&lt;br /&gt;
&lt;br /&gt;
In all, rendering the tree_display page is divided into 3 steps: &amp;lt;br&amp;gt;&lt;br /&gt;
1. render the table frame,  &amp;lt;br&amp;gt;&lt;br /&gt;
2. render the first level table content. &amp;lt;br&amp;gt;&lt;br /&gt;
3. fetch deeper level data. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the past, these 3 steps are done before rendering the page, which takes about 10-20 seconds. But now, it takes only 2-3 seconds to finish the first 2 steps, and 2 more seconds for the 3rd step.&lt;br /&gt;
&lt;br /&gt;
Moreover, the sorting and table record filtering is integrated into the table. No redirecting or re-rendering is needed for sorting or filtering, which was needed in the past.&lt;br /&gt;
&lt;br /&gt;
=== Code details ===&lt;br /&gt;
Pass Rails controller params to view in tree_display_controller#list&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
angularParams = {}&lt;br /&gt;
angularParams[:search] = @search&lt;br /&gt;
angularParams[:show] = @show&lt;br /&gt;
angularParams[:child_nodes] = @child_nodes&lt;br /&gt;
angularParams[:sortvar] = @sortvar&lt;br /&gt;
angularParams[:sortorder] = @sortorder&lt;br /&gt;
angularParams[:user_id] = session[:user].id&lt;br /&gt;
angularParams[:nodeType] = 'FolderNode'&lt;br /&gt;
@angularParamsJSON = angularParams.to_json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then the view passes to AngularJS&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div ng-controller='TreeCtrl'&amp;gt;&lt;br /&gt;
&amp;lt;div ng-init=&amp;quot;init('&amp;lt;%= @angularParamsJSON %&amp;gt;')&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AngularJS handles it, after all basic elements are loaded onto the page. Then AngularJS initializes a POST request for retrieving more data to populate the table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$scope.init = (value) -&amp;gt;&lt;br /&gt;
    $scope.angularParams = JSON.parse(value)&lt;br /&gt;
    $http.post('/tree_display/get_children_node_ng', {&lt;br /&gt;
      &amp;quot;angularParams&amp;quot;: $scope.angularParams&lt;br /&gt;
      })&lt;br /&gt;
    .success((data) -&amp;gt;&lt;br /&gt;
      $scope.tableContent = {}&lt;br /&gt;
      $scope.displayTableContent = {}&lt;br /&gt;
      $scope.lastLoadNum = {}&lt;br /&gt;
      $scope.typeList = []&lt;br /&gt;
      console.log data&lt;br /&gt;
      for nodeType, outerNode of data&lt;br /&gt;
        $scope.tableContent[nodeType] = []&lt;br /&gt;
        $scope.lastLoadNum[nodeType] = 0&lt;br /&gt;
        $scope.displayTableContent[nodeType] = []&lt;br /&gt;
        $scope.typeList.push nodeType&lt;br /&gt;
        # outerNode is the Assignments/Courses/Questionnaires&lt;br /&gt;
        for node in outerNode&lt;br /&gt;
          $scope.tableContent[nodeType].push node&lt;br /&gt;
          $scope.fetchCellContent(nodeType, node)&lt;br /&gt;
        $scope.getMoreContent(nodeType, 1)&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetch table cell content recursively and put them into a hash&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$scope.fetchCellContent = (nodeType, node) -&amp;gt;&lt;br /&gt;
    $scope.newParams = {}&lt;br /&gt;
    $scope.newParams[&amp;quot;sortvar&amp;quot;] = $scope.angularParams[&amp;quot;sortvar&amp;quot;]&lt;br /&gt;
    $scope.newParams[&amp;quot;sortorder&amp;quot;] = $scope.angularParams[&amp;quot;sortorder&amp;quot;]&lt;br /&gt;
    $scope.newParams[&amp;quot;search&amp;quot;] = $scope.angularParams[&amp;quot;search&amp;quot;]&lt;br /&gt;
    $scope.newParams[&amp;quot;show&amp;quot;] = $scope.angularParams[&amp;quot;show&amp;quot;]&lt;br /&gt;
    $scope.newParams[&amp;quot;user_id&amp;quot;] = $scope.angularParams[&amp;quot;user_id&amp;quot;]&lt;br /&gt;
    key = node.name + &amp;quot;|&amp;quot; + node.directory&lt;br /&gt;
    $scope.newParams[&amp;quot;key&amp;quot;] = key&lt;br /&gt;
    # console.log key&lt;br /&gt;
    if nodeType == 'Assignments'&lt;br /&gt;
      $scope.newParams[&amp;quot;nodeType&amp;quot;] = 'AssignmentNode'&lt;br /&gt;
    else if nodeType == 'Courses'&lt;br /&gt;
      $scope.newParams[&amp;quot;nodeType&amp;quot;] = 'CourseNode'&lt;br /&gt;
    else if nodeType == 'Questionnaires'&lt;br /&gt;
      $scope.newParams[&amp;quot;nodeType&amp;quot;] = 'FolderNode'&lt;br /&gt;
    else&lt;br /&gt;
      $scope.newParams[&amp;quot;nodeType&amp;quot;] = nodeType&lt;br /&gt;
&lt;br /&gt;
    $scope.newParams[&amp;quot;child_nodes&amp;quot;] = node.nodeinfo&lt;br /&gt;
    $http.post('/tree_display/get_children_node_2_ng', {&lt;br /&gt;
      &amp;quot;angularParams&amp;quot;: $scope.newParams&lt;br /&gt;
      })&lt;br /&gt;
    .success((data) -&amp;gt;&lt;br /&gt;
      if data.length &amp;gt; 0&lt;br /&gt;
        for newNode in data&lt;br /&gt;
          if not $scope.allData[newNode.key]&lt;br /&gt;
            $scope.allData[newNode.key] = []&lt;br /&gt;
          $scope.display[newNode.key] = false&lt;br /&gt;
          $scope.allData[newNode.key].push newNode&lt;br /&gt;
          $scope.fetchCellContent(newNode.type, newNode)&lt;br /&gt;
&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After all data is fetched, the Rails view is able to presenting them onto the page!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;tbody ng-repeat=&amp;quot;record in displayTableContent['Courses'] | filter:searchText | orderBy:predicate:reverse&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;tr ng-click=&amp;quot;showCellContent(record.name, record.directory)&amp;quot; class=&amp;quot;clickable-row&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;td&amp;gt;{{record.name}}&amp;lt;/td&amp;gt;&lt;br /&gt;
            &amp;lt;td&amp;gt;{{record.directory}}&amp;lt;/td&amp;gt;&lt;br /&gt;
            &amp;lt;td&amp;gt;{{record.creation_date}}&amp;lt;/td&amp;gt;&lt;br /&gt;
            &amp;lt;td&amp;gt;{{record.updated_date}}&amp;lt;/td&amp;gt;&lt;br /&gt;
            &amp;lt;td&amp;gt;&lt;br /&gt;
              &lt;br /&gt;
            &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          &amp;lt;/tr&amp;gt;&lt;br /&gt;
          &amp;lt;tr class=&amp;quot;no-cursor-tr no-color-tr&amp;quot; ng-if=&amp;quot;display[record.name+'|'+record.directory] &amp;amp;&amp;amp; allData[record.name+'|'+record.directory]&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;table class=&amp;quot;normal-table table table-bordered table-striped compact-table&amp;quot; ng-repeat=&amp;quot;cell in cellContent&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;tbody&amp;gt;&lt;br /&gt;
                &amp;lt;tr class=&amp;quot;no-cursor-tr no-color-tr&amp;quot;&amp;gt;&lt;br /&gt;
                  &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;: {{cell.name}}&amp;lt;/td&amp;gt;&lt;br /&gt;
                &amp;lt;/tr&amp;gt;&lt;br /&gt;
                &amp;lt;tr class=&amp;quot;no-cursor-tr no-color-tr&amp;quot;&amp;gt;&lt;br /&gt;
                  &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;Directory&amp;lt;/b&amp;gt;: {{cell.directory}}&amp;lt;/td&amp;gt;&lt;br /&gt;
                &amp;lt;/tr&amp;gt;&lt;br /&gt;
                &amp;lt;tr class=&amp;quot;no-cursor-tr no-color-tr&amp;quot;&amp;gt;&lt;br /&gt;
                  &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;Creation Date&amp;lt;/b&amp;gt;: {{cell.creation_date}}&amp;lt;/td&amp;gt;&lt;br /&gt;
                &amp;lt;/tr&amp;gt;&lt;br /&gt;
                &amp;lt;tr class=&amp;quot;no-cursor-tr no-color-tr&amp;quot;&amp;gt;&lt;br /&gt;
                  &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;Modified Date&amp;lt;/b&amp;gt;: {{cell.updated_date}}&amp;lt;/td&amp;gt;&lt;br /&gt;
                &amp;lt;/tr&amp;gt;&lt;br /&gt;
              &amp;lt;/tbody&amp;gt;&lt;br /&gt;
            &amp;lt;/table&amp;gt;&lt;br /&gt;
          &amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manage Users page ==&lt;br /&gt;
&lt;br /&gt;
===Design===&lt;br /&gt;
&lt;br /&gt;
Once logged in, choosing Manage/users option from the navbar, gets us routed to /users page which is defined in list.html.erb file. This file can be broken down to 5 constituents:&lt;br /&gt;
&lt;br /&gt;
1) Fetching Users &amp;lt;br&amp;gt;&lt;br /&gt;
2) Paginating Users &amp;lt;br&amp;gt;&lt;br /&gt;
3) Searching Users &amp;lt;br&amp;gt;&lt;br /&gt;
4) Showing Users &amp;lt;br&amp;gt;&lt;br /&gt;
5) Editing and Deleting Users &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Code Details===&lt;br /&gt;
&lt;br /&gt;
1) Fetching Users&lt;br /&gt;
Fetching users was challenging at first due to an extremely large number of user entries (total of 5300). Fetch of such large data produced a very long delay that was one of the major UX problems in legacy version of Expertiza. This problem has been solved with Angular by sending a post request that gets 300 users and then another post request which gets all the users. This approach provides a quick response and the first 300 users can be seen right away in the form of 3 pages (default set to 100 users per page). While the user is looking at the first couple of entries, the rest of the entries are fetched in the background. This allows for a fast response, full functionality as well as complete data.&lt;br /&gt;
&lt;br /&gt;
In app/assets/javascripts/app.coffee:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$scope.getUsers = (fn) -&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    $http.post('/users/get_users_ng', {&lt;br /&gt;
      'fetchNumber': fn&lt;br /&gt;
    })&lt;br /&gt;
    .success((receivedUsers) -&amp;gt;&lt;br /&gt;
      console.log receivedUsers&lt;br /&gt;
      for user in receivedUsers&lt;br /&gt;
        $scope.users.push user&lt;br /&gt;
        $scope.user_display[user.object.id] = false&lt;br /&gt;
        $scope.editProfileVisible[user.object.id] = false&lt;br /&gt;
&lt;br /&gt;
      $scope.fetchNumber+=1&lt;br /&gt;
      console.log $scope.users.length&lt;br /&gt;
      console.log $scope.listSize&lt;br /&gt;
&lt;br /&gt;
      if $scope.users.length &amp;lt; $scope.listSize&lt;br /&gt;
        $scope.getUsers($scope.fetchNumber)&lt;br /&gt;
      )&lt;br /&gt;
&lt;br /&gt;
  $scope.getUserListSize = () -&amp;gt;&lt;br /&gt;
    $http.get('/users/get_users_list_ng')&lt;br /&gt;
    .success((listSize) -&amp;gt;&lt;br /&gt;
      $scope.listSize = listSize&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This process is initiated by init() command shown bellow:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$scope.init = (value) -&amp;gt;&lt;br /&gt;
    $scope.user_display = {}&lt;br /&gt;
    $scope.editProfileVisible = {}&lt;br /&gt;
    if $scope.users.length == $scope.listSize&lt;br /&gt;
      return&lt;br /&gt;
    else if $scope.users.length == 0&lt;br /&gt;
      $scope.listSize = 0&lt;br /&gt;
      $scope.getUserListSize()&lt;br /&gt;
      $scope.fetchNumber = 0&lt;br /&gt;
    $scope.getUsers(($scope.fetchNumber))&lt;br /&gt;
    $scope.currentPage = 0&lt;br /&gt;
    $scope.pagination(50)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Paginating Users&lt;br /&gt;
&lt;br /&gt;
In order to paginate users, a filter needs to be set in order to limit the number of users being shown:&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;tbody ng-repeat=&amp;quot;user in users | filter:search | startFrom:currentPage*pageSize | limitTo:pageSize&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;tr ng-click=&amp;quot;showUser(user.object.id)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.name}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.fullname}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.email}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.role}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.parent}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_review}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_submission}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_review_of_review}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.leaderboard_privacy}}&amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The startFrom:currentPage*pageSize portion of the filter calls the custom filter startFrom which simply splits the data to display based on the current page of pagination (currentPage), multiplied by the number of users to display (pageSize, which is set by the user selecting either All, 25, 50, 100, or 250).&lt;br /&gt;
&lt;br /&gt;
In app/assets/javascripts/app.coffee:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app.filter 'startFrom', -&amp;gt;&lt;br /&gt;
  (input, start) -&amp;gt;&lt;br /&gt;
    start = +start&lt;br /&gt;
    return input.slice start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The limitTo:pageSize is a built in angular filter that says to stop displaying users after pageSize of them have been displayed.&lt;br /&gt;
&lt;br /&gt;
The aforementioned pageSize is set by the user through a dropdown; This code tells the dropdown to set the default paginate value to 100 users per page, and upon an ng-change (user selecting a different value), the pagination method will be called in app.coffee, with the appropriate pageSize:&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;label&amp;gt;Paginate By: &lt;br /&gt;
    &amp;lt;select class=&amp;quot;form-control&amp;quot; ng-model=&amp;quot;paginate&amp;quot; ng-init=&amp;quot;paginate='50'&amp;quot; ng-change=&amp;quot;pagination(paginate)&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;0&amp;quot;&amp;gt;All&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;25&amp;quot;&amp;gt;25&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;50&amp;quot;&amp;gt;50&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;100&amp;quot;&amp;gt;100&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;250&amp;quot;&amp;gt;250&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;/label&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code is in app.coffee, and it posts the pageSize to the set_page_size method in the users_controller, and then sets various variable values based on the results:&lt;br /&gt;
&lt;br /&gt;
In app/assets/javascripts/app.coffee:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$scope.pagination = (ps) -&amp;gt;&lt;br /&gt;
    $http.post('/users/set_page_size', {&lt;br /&gt;
      'pageSize': ps&lt;br /&gt;
    })&lt;br /&gt;
    .success((value) -&amp;gt;&lt;br /&gt;
      $scope.pageSize = value[0]&lt;br /&gt;
      $scope.div = value[1]&lt;br /&gt;
      $scope.totalSize = value[2]&lt;br /&gt;
      )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code is in users_controller and it takes in the user defined pageSize variable and then determines how many pages are required to divide the data into based off of the pageSize, then returns that variable, plus others:&lt;br /&gt;
&lt;br /&gt;
In app/controllers/user_controller:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def set_page_size&lt;br /&gt;
    ps = params[:pageSize].to_i&lt;br /&gt;
    user = session[:user]&lt;br /&gt;
    role = Role.find(user.role_id)&lt;br /&gt;
    all_users = User.order('name').where( ['role_id in (?) or id = ?', role.get_available_roles, user.id])&lt;br /&gt;
    users_length = all_users.length&lt;br /&gt;
    if ps == 0&lt;br /&gt;
      pageSize = users_length&lt;br /&gt;
    else&lt;br /&gt;
      pageSize = ps&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    div = (users_length/pageSize.to_f).ceil&lt;br /&gt;
    &lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      format.html {render json: [pageSize, div, users_length]}&lt;br /&gt;
    end&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the number of pages and pageSize has been set, those numbers are then used to show the current and remaining pages to go along with the previous and next buttons:&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;paginate-button&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;button class=&amp;quot;glyphicon glyphicon-chevron-left&amp;quot; ng-disabled=&amp;quot;currentPage == 0&amp;quot; ng-click=&amp;quot;currentPage=currentPage-1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
  {{currentPage+1}}/{{div}}&lt;br /&gt;
  &amp;lt;button class=&amp;quot;glyphicon glyphicon-chevron-right&amp;quot; ng-disabled=&amp;quot;currentPage &amp;gt;= totalSize/pageSize - 1&amp;quot; ng-click=&amp;quot;currentPage=currentPage+1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Searching Users&lt;br /&gt;
In order to search users, a filter also needs to be set in order to limit the number of users being shown:&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;tbody ng-repeat=&amp;quot;user in users | filter:search | startFrom:currentPage*pageSize | limitTo:pageSize&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;tr ng-click=&amp;quot;showUser(user.object.id)&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.name}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.fullname}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.object.email}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.role}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.parent}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_review}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_submission}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.email_on_review_of_review}}&amp;lt;/td&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;{{user.leaderboard_privacy}}&amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The filter:search portion of this code simply applies the following filter criteria; the type of search is determined a dropdown (either search by any field, name, fullname, or email fields). Based on the dropdown selection, the correct search box will be shown, once that search box is show, the search criteria is set to correspond to the type of search specified by the dropdown:&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;pull-right form-group&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;form-inline&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label&amp;gt;Search By: &lt;br /&gt;
    &amp;lt;select class=&amp;quot;form-control&amp;quot; ng-model=&amp;quot;searchtype&amp;quot; ng-init=&amp;quot;searchtype='any'&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;any&amp;quot;&amp;gt;Any&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;name&amp;quot;&amp;gt;Name&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;fullname&amp;quot;&amp;gt;Full Name&amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;option value=&amp;quot;email&amp;quot;&amp;gt;Email&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
  &amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input class=&amp;quot;form-control&amp;quot; ng-hide=&amp;quot;searchtype != 'any'&amp;quot; ng-model=&amp;quot;search.object.$&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input class=&amp;quot;form-control&amp;quot; ng-hide=&amp;quot;searchtype != 'name'&amp;quot; ng-model=&amp;quot;search.object.name&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input class=&amp;quot;form-control&amp;quot; ng-hide=&amp;quot;searchtype != 'fullname'&amp;quot; ng-model=&amp;quot;search.object.fullname&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input class=&amp;quot;form-control&amp;quot; ng-hide=&amp;quot;searchtype != 'email'&amp;quot; ng-model=&amp;quot;search.object.email&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Showing Users&lt;br /&gt;
Clicking on each user name in the table of users uncovers a template that shows the information about that specific user. This is accomplished in a very simple way by setting the profileVisible flag to true. The information about that specific user is extracted from displayedUser object provided by showUser() method from UsersPageCtrl controller in app.coffee file.&lt;br /&gt;
&lt;br /&gt;
In views/users/list.html.erb:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div ng-if=&amp;quot;profileVisible == true&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;&amp;lt;b&amp;gt;User: {{displayedUser.object.name}}&amp;lt;/b&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;h3&amp;gt;&amp;lt;b&amp;gt;Full Name: &amp;lt;/b&amp;gt;{{displayedUser.object.fullname}}&amp;lt;/h3&amp;gt;&lt;br /&gt;
  &amp;lt;h3&amp;gt;&amp;lt;b&amp;gt;Email Address: &amp;lt;/b&amp;gt;{{displayedUser.object.email}}&amp;lt;/h3&amp;gt;&lt;br /&gt;
  &amp;lt;h3&amp;gt;&amp;lt;b&amp;gt;Role: &amp;lt;/b&amp;gt;{{displayedUser.role}}&amp;lt;/h3&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;button ng-click=&amp;quot;showTable(true)&amp;quot; type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-primary&amp;quot;&amp;gt;Back&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;button ng-click=&amp;quot;editUser()&amp;quot; type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-success&amp;quot;&amp;gt;Edit&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;button ng-click=&amp;quot;deleteUser()&amp;quot; type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-danger&amp;quot;&amp;gt;Delete&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In app/assets/javascripts/app.coffee:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $scope.showUser = (user_id) -&amp;gt;&lt;br /&gt;
    $scope.user_display[user_id] = !$scope.user_display[user_id]&lt;br /&gt;
    $scope.editProfileVisible[user_id] = false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
5) Editing and Deleting Users&lt;br /&gt;
&lt;br /&gt;
Editing Users is implemented in a similar way as showing users. The template contains ng-if statement which allows us to display edit page for each user. editUser() method from UsersPageCtrl controller specified in app.coffee displays information of the displayedUser but only after the Save button is clicked it saves the information from displayedUsers into updatedUser variable. POST request with :id parameter is then sent to update method in users_controller of Rails, which then updates this user information in the database.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $scope.editUser = (user) -&amp;gt;&lt;br /&gt;
    # $scope.showUser(false)&lt;br /&gt;
    $scope.editProfileVisible[user.object.id] = !$scope.editProfileVisible[user.object.id]&lt;br /&gt;
    $scope.updatedUser = user&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95986</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95986"/>
		<updated>2015-03-24T21:06:52Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;In order to run our code vist: 152.46.20.14:1 (VNC Viewer) or 152.46.20.14:5801 (browser), and use the password: password to log in. Please leave the system like you found it (with the browser open, and set to localhost:3000).&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction to Expertiza=&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). The Expertiza project is supported by the National Science Foundation.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;[http://wikis.lib.ncsu.edu/index.php/Expertiza Wiki]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods. The method had some special code that was moved out. Could not move the logic for creating new reviews out of rereview since the new reviews were not created by rereview but instead was using the create method in response_controller.rb&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Renaming latestResponseVersion method==&lt;br /&gt;
The latestResponseVersion method is misnamed. It fetches all the previous versions of a response and its current name does not reflect its actual functionality. The method was renamed as previous_responses since it better suited the actual functionality.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
 def latestResponseVersion&lt;br /&gt;
    #get all previous versions of responses for the response map.&lt;br /&gt;
    @review_scores=Array.new&lt;br /&gt;
    @prev=Response.where(map_id: @map.id)&lt;br /&gt;
    for element in @prev&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; element&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
     for element in @prev&lt;br /&gt;
      if (element.map.id==@map.map.id)&lt;br /&gt;
        array_not_empty=1&lt;br /&gt;
        @review_scores &amp;lt;&amp;lt; element&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    latestResponseVersion&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In method create&lt;br /&gt;
&lt;br /&gt;
    @map = ResponseMap.find(params[:id]) #assignment/review/metareview id is in params id&lt;br /&gt;
    @res = 0&lt;br /&gt;
    msg = &amp;quot;&amp;quot;&lt;br /&gt;
    error_msg = &amp;quot;&amp;quot;&lt;br /&gt;
    latestResponseVersion&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
 def previous_responses&lt;br /&gt;
    #get all previous versions of responses for the response map.&lt;br /&gt;
    @review_scores=Array.new&lt;br /&gt;
    @prev=Response.where(map_id: @map.id)&lt;br /&gt;
    for element in @prev&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; element&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
    @map=ResponseMap.find(params[:id])&lt;br /&gt;
    # store response content in map&lt;br /&gt;
    get_content&lt;br /&gt;
    previous_responses&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In method create&lt;br /&gt;
&lt;br /&gt;
    @map = ResponseMap.find(params[:id]) #assignment/review/metareview id is in params id&lt;br /&gt;
    @res = 0&lt;br /&gt;
    msg = &amp;quot;&amp;quot;&lt;br /&gt;
    error_msg = &amp;quot;&amp;quot;&lt;br /&gt;
    previous_responses&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving the sorting of response versions logic out of rereview method==&lt;br /&gt;
The code to sort response versions has been moved from rereview method to a separate method. This was done because the rereview method was becoming very long and confusing.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
       def rereview&lt;br /&gt;
    @map=ResponseMap.find(params[:id])&lt;br /&gt;
    get_content&lt;br /&gt;
    array_not_empty=0&lt;br /&gt;
    @review_scores=Array.new&lt;br /&gt;
    @prev=Response.all&lt;br /&gt;
    #get all versions and find the latest version&lt;br /&gt;
    for element in @prev&lt;br /&gt;
      if (element.map.id==@map.map.id)&lt;br /&gt;
        array_not_empty=1&lt;br /&gt;
        @review_scores &amp;lt;&amp;lt; element&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    latestResponseVersion&lt;br /&gt;
    #sort all the available versions in descending order.&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted=@review_scores.sort { |m1, m2| (m1.version_num and m2.version_num) ? m2.version_num &amp;lt;=&amp;gt; m1.version_num : (m1.version_num ? -1 : 1) }&lt;br /&gt;
      @largest_version_num=@sorted[0]&lt;br /&gt;
      @latest_phase=@largest_version_num.created_at&lt;br /&gt;
      due_dates = DueDate.where([&amp;quot;assignment_id = ?&amp;quot;, @assignment.id])&lt;br /&gt;
      @sorted_deadlines=Array.new&lt;br /&gt;
      @sorted_deadlines=due_dates.sort { |m1, m2| (m1.due_at and m2.due_at) ? m1.due_at &amp;lt;=&amp;gt; m2.due_at : (m1.due_at ? -1 : 1) }&lt;br /&gt;
      current_time=Time.new.getutc&lt;br /&gt;
      #get the highest version numbered review&lt;br /&gt;
      next_due_date=@sorted_deadlines[0]&lt;br /&gt;
      #check in which phase the latest review was done.&lt;br /&gt;
      for deadline_version in @sorted_deadlines&lt;br /&gt;
        if (@largest_version_num.created_at &amp;lt; deadline_version.due_at)&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
   def rereview&lt;br /&gt;
    @map=ResponseMap.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    # store response content in map&lt;br /&gt;
    get_content&lt;br /&gt;
&lt;br /&gt;
    previous_responses&lt;br /&gt;
    #sort all the available versions in descending order.&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      sortResponseVersion&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def sortResponseVersion&lt;br /&gt;
    @sorted=@review_scores.sort { |m1, m2| (m1.version_num and m2.version_num) ? m2.version_num &amp;lt;=&amp;gt; m1.version_num : (m1.version_num ? -1 : 1) }&lt;br /&gt;
    @largest_version_num=@sorted[0]&lt;br /&gt;
    @latest_phase=@largest_version_num.created_at&lt;br /&gt;
    due_dates = DueDate.where([&amp;quot;assignment_id = ?&amp;quot;, @assignment.id])&lt;br /&gt;
    @sorted_deadlines=Array.new&lt;br /&gt;
    @sorted_deadlines=due_dates.sort { |m1, m2| (m1.due_at and m2.due_at) ? m1.due_at &amp;lt;=&amp;gt; m2.due_at : (m1.due_at ? -1 : 1) }&lt;br /&gt;
    current_time=Time.new.getutc&lt;br /&gt;
    #get the highest version numbered review&lt;br /&gt;
    next_due_date=@sorted_deadlines[0]&lt;br /&gt;
    #check in which phase the latest review was done.&lt;br /&gt;
    for deadline_version in @sorted_deadlines&lt;br /&gt;
      if (@largest_version_num.created_at &amp;lt; deadline_version.due_at)&lt;br /&gt;
        break&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    for deadline_time in @sorted_deadlines&lt;br /&gt;
      if (current_time &amp;lt; deadline_time.due_at)&lt;br /&gt;
        break&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removing special code in rereview method==&lt;br /&gt;
The rereview method had some special code to check if the current user is jace_smith and uses a custom hard-coded rubric instead of a rubric from the system. This was a code segment that was written when multipart rubrics were first tested. Removing this code will break the assignment and so the code was moved to a separate method and commented as a kludge.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
       #**********************&lt;br /&gt;
      # Check whether this is Jen's assgt. &amp;amp; if so, use her rubric&lt;br /&gt;
      if (@assignment.instructor_id == User.find_by_name(&amp;quot;jace_smith&amp;quot;).id) &amp;amp;&amp;amp; @title == &amp;quot;Review&amp;quot;&lt;br /&gt;
        if @assignment.id &amp;lt; 469&lt;br /&gt;
          @next_action = &amp;quot;update&amp;quot;&lt;br /&gt;
          render :action =&amp;gt; 'custom_response'&lt;br /&gt;
        else&lt;br /&gt;
          @next_action = &amp;quot;update&amp;quot;&lt;br /&gt;
          render :action =&amp;gt; 'custom_response_2011'&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # end of special code (except for the end below, to match the if above)&lt;br /&gt;
        #**********************&lt;br /&gt;
        render :action =&amp;gt; 'response'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      #else create a new version and update it.&lt;br /&gt;
      @header = &amp;quot;New&amp;quot;&lt;br /&gt;
      @next_action = &amp;quot;create&amp;quot;&lt;br /&gt;
      @feedback = params[:feedback]&lt;br /&gt;
      @map = ResponseMap.find(params[:id])&lt;br /&gt;
      @return = params[:return]&lt;br /&gt;
      @modified_object = @map.map_id&lt;br /&gt;
      get_content&lt;br /&gt;
      #**********************&lt;br /&gt;
      # Check whether this is Jen's assgt. &amp;amp; if so, use her rubric&lt;br /&gt;
      if (@assignment.instructor_id == User.find_by_name(&amp;quot;jace_smith&amp;quot;).id) &amp;amp;&amp;amp; @title == &amp;quot;Review&amp;quot;&lt;br /&gt;
        if @assignment.id &amp;lt; 469&lt;br /&gt;
          @next_action = &amp;quot;create&amp;quot;&lt;br /&gt;
          render :action =&amp;gt; 'custom_response'&lt;br /&gt;
        else&lt;br /&gt;
          @next_action = &amp;quot;create&amp;quot;&lt;br /&gt;
          render :action =&amp;gt; 'custom_response_2011'&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # end of special code (except for the end below, to match the if above)&lt;br /&gt;
        #**********************&lt;br /&gt;
        render :action =&amp;gt; 'response'&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
  # Check whether this is Jen's assgt. &amp;amp; if so, use her rubric&lt;br /&gt;
      if (@assignment.instructor_id == User.find_by_name(&amp;quot;jace_smith&amp;quot;).id) &amp;amp;&amp;amp; @title == &amp;quot;Review&amp;quot;&lt;br /&gt;
        handle_jens_assignment&lt;br /&gt;
      else &lt;br /&gt;
        render :action =&amp;gt; 'response'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      #else create a new version and update it.&lt;br /&gt;
      @header = &amp;quot;New&amp;quot;&lt;br /&gt;
      @next_action = &amp;quot;create&amp;quot;&lt;br /&gt;
      @feedback = params[:feedback]&lt;br /&gt;
      @map = ResponseMap.find(params[:id])&lt;br /&gt;
      @return = params[:return]&lt;br /&gt;
      @modified_object = @map.map_id&lt;br /&gt;
      get_content&lt;br /&gt;
      # Check whether this is Jen's assgt. &amp;amp; if so, use her rubric&lt;br /&gt;
      if (@assignment.instructor_id == User.find_by_name(&amp;quot;jace_smith&amp;quot;).id) &amp;amp;&amp;amp; @title == &amp;quot;Review&amp;quot;&lt;br /&gt;
        handle_jens_assignment&lt;br /&gt;
      else&lt;br /&gt;
        render :action =&amp;gt; 'response'&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #kludge for checking if assignment is jen's assignment and using her rubric if it is&lt;br /&gt;
  def handle_jens_assignment&lt;br /&gt;
    if @assignment.id &amp;lt; 469&lt;br /&gt;
      @next_action = &amp;quot;update&amp;quot;&lt;br /&gt;
      render :action =&amp;gt; 'custom_response'&lt;br /&gt;
    else&lt;br /&gt;
      @next_action = &amp;quot;update&amp;quot;&lt;br /&gt;
      render :action =&amp;gt; 'custom_response_2011'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores  ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct.&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Review done at --2013-03-01 23:57:55 UTC&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the get_scores method.&lt;br /&gt;
&lt;br /&gt;
== rereview  ==&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review (i.e. 'rereview').&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Update (beside Metaprogramming in dynamically typed languages)&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the rereview method.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references&amp;gt;&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95985</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95985"/>
		<updated>2015-03-24T21:06:39Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
In order to run our code vist: 152.46.20.14:1 (VNC Viewer) or 152.46.20.14:5801 (browser), and use the password: password to log in. Please leave the system like you found it (with the browser open, and set to localhost:3000).&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction to Expertiza=&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). The Expertiza project is supported by the National Science Foundation.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;[http://wikis.lib.ncsu.edu/index.php/Expertiza Wiki]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods. The method had some special code that was moved out. Could not move the logic for creating new reviews out of rereview since the new reviews were not created by rereview but instead was using the create method in response_controller.rb&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Renaming latestResponseVersion method==&lt;br /&gt;
The latestResponseVersion method is misnamed. It fetches all the previous versions of a response and its current name does not reflect its actual functionality. The method was renamed as previous_responses since it better suited the actual functionality.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
 def latestResponseVersion&lt;br /&gt;
    #get all previous versions of responses for the response map.&lt;br /&gt;
    @review_scores=Array.new&lt;br /&gt;
    @prev=Response.where(map_id: @map.id)&lt;br /&gt;
    for element in @prev&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; element&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
     for element in @prev&lt;br /&gt;
      if (element.map.id==@map.map.id)&lt;br /&gt;
        array_not_empty=1&lt;br /&gt;
        @review_scores &amp;lt;&amp;lt; element&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    latestResponseVersion&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In method create&lt;br /&gt;
&lt;br /&gt;
    @map = ResponseMap.find(params[:id]) #assignment/review/metareview id is in params id&lt;br /&gt;
    @res = 0&lt;br /&gt;
    msg = &amp;quot;&amp;quot;&lt;br /&gt;
    error_msg = &amp;quot;&amp;quot;&lt;br /&gt;
    latestResponseVersion&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
 def previous_responses&lt;br /&gt;
    #get all previous versions of responses for the response map.&lt;br /&gt;
    @review_scores=Array.new&lt;br /&gt;
    @prev=Response.where(map_id: @map.id)&lt;br /&gt;
    for element in @prev&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; element&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
    @map=ResponseMap.find(params[:id])&lt;br /&gt;
    # store response content in map&lt;br /&gt;
    get_content&lt;br /&gt;
    previous_responses&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In method create&lt;br /&gt;
&lt;br /&gt;
    @map = ResponseMap.find(params[:id]) #assignment/review/metareview id is in params id&lt;br /&gt;
    @res = 0&lt;br /&gt;
    msg = &amp;quot;&amp;quot;&lt;br /&gt;
    error_msg = &amp;quot;&amp;quot;&lt;br /&gt;
    previous_responses&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving the sorting of response versions logic out of rereview method==&lt;br /&gt;
The code to sort response versions has been moved from rereview method to a separate method. This was done because the rereview method was becoming very long and confusing.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
       def rereview&lt;br /&gt;
    @map=ResponseMap.find(params[:id])&lt;br /&gt;
    get_content&lt;br /&gt;
    array_not_empty=0&lt;br /&gt;
    @review_scores=Array.new&lt;br /&gt;
    @prev=Response.all&lt;br /&gt;
    #get all versions and find the latest version&lt;br /&gt;
    for element in @prev&lt;br /&gt;
      if (element.map.id==@map.map.id)&lt;br /&gt;
        array_not_empty=1&lt;br /&gt;
        @review_scores &amp;lt;&amp;lt; element&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    latestResponseVersion&lt;br /&gt;
    #sort all the available versions in descending order.&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted=@review_scores.sort { |m1, m2| (m1.version_num and m2.version_num) ? m2.version_num &amp;lt;=&amp;gt; m1.version_num : (m1.version_num ? -1 : 1) }&lt;br /&gt;
      @largest_version_num=@sorted[0]&lt;br /&gt;
      @latest_phase=@largest_version_num.created_at&lt;br /&gt;
      due_dates = DueDate.where([&amp;quot;assignment_id = ?&amp;quot;, @assignment.id])&lt;br /&gt;
      @sorted_deadlines=Array.new&lt;br /&gt;
      @sorted_deadlines=due_dates.sort { |m1, m2| (m1.due_at and m2.due_at) ? m1.due_at &amp;lt;=&amp;gt; m2.due_at : (m1.due_at ? -1 : 1) }&lt;br /&gt;
      current_time=Time.new.getutc&lt;br /&gt;
      #get the highest version numbered review&lt;br /&gt;
      next_due_date=@sorted_deadlines[0]&lt;br /&gt;
      #check in which phase the latest review was done.&lt;br /&gt;
      for deadline_version in @sorted_deadlines&lt;br /&gt;
        if (@largest_version_num.created_at &amp;lt; deadline_version.due_at)&lt;br /&gt;
          break&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
   def rereview&lt;br /&gt;
    @map=ResponseMap.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    # store response content in map&lt;br /&gt;
    get_content&lt;br /&gt;
&lt;br /&gt;
    previous_responses&lt;br /&gt;
    #sort all the available versions in descending order.&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      sortResponseVersion&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def sortResponseVersion&lt;br /&gt;
    @sorted=@review_scores.sort { |m1, m2| (m1.version_num and m2.version_num) ? m2.version_num &amp;lt;=&amp;gt; m1.version_num : (m1.version_num ? -1 : 1) }&lt;br /&gt;
    @largest_version_num=@sorted[0]&lt;br /&gt;
    @latest_phase=@largest_version_num.created_at&lt;br /&gt;
    due_dates = DueDate.where([&amp;quot;assignment_id = ?&amp;quot;, @assignment.id])&lt;br /&gt;
    @sorted_deadlines=Array.new&lt;br /&gt;
    @sorted_deadlines=due_dates.sort { |m1, m2| (m1.due_at and m2.due_at) ? m1.due_at &amp;lt;=&amp;gt; m2.due_at : (m1.due_at ? -1 : 1) }&lt;br /&gt;
    current_time=Time.new.getutc&lt;br /&gt;
    #get the highest version numbered review&lt;br /&gt;
    next_due_date=@sorted_deadlines[0]&lt;br /&gt;
    #check in which phase the latest review was done.&lt;br /&gt;
    for deadline_version in @sorted_deadlines&lt;br /&gt;
      if (@largest_version_num.created_at &amp;lt; deadline_version.due_at)&lt;br /&gt;
        break&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    for deadline_time in @sorted_deadlines&lt;br /&gt;
      if (current_time &amp;lt; deadline_time.due_at)&lt;br /&gt;
        break&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Removing special code in rereview method==&lt;br /&gt;
The rereview method had some special code to check if the current user is jace_smith and uses a custom hard-coded rubric instead of a rubric from the system. This was a code segment that was written when multipart rubrics were first tested. Removing this code will break the assignment and so the code was moved to a separate method and commented as a kludge.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
       #**********************&lt;br /&gt;
      # Check whether this is Jen's assgt. &amp;amp; if so, use her rubric&lt;br /&gt;
      if (@assignment.instructor_id == User.find_by_name(&amp;quot;jace_smith&amp;quot;).id) &amp;amp;&amp;amp; @title == &amp;quot;Review&amp;quot;&lt;br /&gt;
        if @assignment.id &amp;lt; 469&lt;br /&gt;
          @next_action = &amp;quot;update&amp;quot;&lt;br /&gt;
          render :action =&amp;gt; 'custom_response'&lt;br /&gt;
        else&lt;br /&gt;
          @next_action = &amp;quot;update&amp;quot;&lt;br /&gt;
          render :action =&amp;gt; 'custom_response_2011'&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # end of special code (except for the end below, to match the if above)&lt;br /&gt;
        #**********************&lt;br /&gt;
        render :action =&amp;gt; 'response'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      #else create a new version and update it.&lt;br /&gt;
      @header = &amp;quot;New&amp;quot;&lt;br /&gt;
      @next_action = &amp;quot;create&amp;quot;&lt;br /&gt;
      @feedback = params[:feedback]&lt;br /&gt;
      @map = ResponseMap.find(params[:id])&lt;br /&gt;
      @return = params[:return]&lt;br /&gt;
      @modified_object = @map.map_id&lt;br /&gt;
      get_content&lt;br /&gt;
      #**********************&lt;br /&gt;
      # Check whether this is Jen's assgt. &amp;amp; if so, use her rubric&lt;br /&gt;
      if (@assignment.instructor_id == User.find_by_name(&amp;quot;jace_smith&amp;quot;).id) &amp;amp;&amp;amp; @title == &amp;quot;Review&amp;quot;&lt;br /&gt;
        if @assignment.id &amp;lt; 469&lt;br /&gt;
          @next_action = &amp;quot;create&amp;quot;&lt;br /&gt;
          render :action =&amp;gt; 'custom_response'&lt;br /&gt;
        else&lt;br /&gt;
          @next_action = &amp;quot;create&amp;quot;&lt;br /&gt;
          render :action =&amp;gt; 'custom_response_2011'&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        # end of special code (except for the end below, to match the if above)&lt;br /&gt;
        #**********************&lt;br /&gt;
        render :action =&amp;gt; 'response'&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In method rereview&lt;br /&gt;
&lt;br /&gt;
  # Check whether this is Jen's assgt. &amp;amp; if so, use her rubric&lt;br /&gt;
      if (@assignment.instructor_id == User.find_by_name(&amp;quot;jace_smith&amp;quot;).id) &amp;amp;&amp;amp; @title == &amp;quot;Review&amp;quot;&lt;br /&gt;
        handle_jens_assignment&lt;br /&gt;
      else &lt;br /&gt;
        render :action =&amp;gt; 'response'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      #else create a new version and update it.&lt;br /&gt;
      @header = &amp;quot;New&amp;quot;&lt;br /&gt;
      @next_action = &amp;quot;create&amp;quot;&lt;br /&gt;
      @feedback = params[:feedback]&lt;br /&gt;
      @map = ResponseMap.find(params[:id])&lt;br /&gt;
      @return = params[:return]&lt;br /&gt;
      @modified_object = @map.map_id&lt;br /&gt;
      get_content&lt;br /&gt;
      # Check whether this is Jen's assgt. &amp;amp; if so, use her rubric&lt;br /&gt;
      if (@assignment.instructor_id == User.find_by_name(&amp;quot;jace_smith&amp;quot;).id) &amp;amp;&amp;amp; @title == &amp;quot;Review&amp;quot;&lt;br /&gt;
        handle_jens_assignment&lt;br /&gt;
      else&lt;br /&gt;
        render :action =&amp;gt; 'response'&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #kludge for checking if assignment is jen's assignment and using her rubric if it is&lt;br /&gt;
  def handle_jens_assignment&lt;br /&gt;
    if @assignment.id &amp;lt; 469&lt;br /&gt;
      @next_action = &amp;quot;update&amp;quot;&lt;br /&gt;
      render :action =&amp;gt; 'custom_response'&lt;br /&gt;
    else&lt;br /&gt;
      @next_action = &amp;quot;update&amp;quot;&lt;br /&gt;
      render :action =&amp;gt; 'custom_response_2011'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores  ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct.&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Review done at --2013-03-01 23:57:55 UTC&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the get_scores method.&lt;br /&gt;
&lt;br /&gt;
== rereview  ==&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review (i.e. 'rereview').&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Update (beside Metaprogramming in dynamically typed languages)&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the rereview method.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references&amp;gt;&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95592</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95592"/>
		<updated>2015-03-23T03:54:54Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Introduction to Expertiza */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction to Expertiza=&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). The Expertiza project is supported by the National Science Foundation.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;[http://wikis.lib.ncsu.edu/index.php/Expertiza Wiki]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores  ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct.&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Review done at --2013-03-01 23:57:55 UTC&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the get_scores method.&lt;br /&gt;
&lt;br /&gt;
== rereview  ==&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review (i.e. 'rereview').&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Update (beside Metaprogramming in dynamically typed languages)&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the rereview method.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references&amp;gt;&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95591</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95591"/>
		<updated>2015-03-23T03:54:23Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Introduction to Expertiza=&lt;br /&gt;
Expertiza is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). The Expertiza project is supported by the National Science Foundation.&amp;lt;ref&amp;gt;[http://expertiza.ncsu.edu/ Expertiza]&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;[http://wikis.lib.ncsu.edu/index.php/Expertiza]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores  ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct.&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Review done at --2013-03-01 23:57:55 UTC&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the get_scores method.&lt;br /&gt;
&lt;br /&gt;
== rereview  ==&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review (i.e. 'rereview').&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Update (beside Metaprogramming in dynamically typed languages)&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the rereview method.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references&amp;gt;&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95590</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95590"/>
		<updated>2015-03-23T03:49:46Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* rereview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores  ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct.&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Review done at --2013-03-01 23:57:55 UTC&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the get_scores method.&lt;br /&gt;
&lt;br /&gt;
== rereview  ==&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review (i.e. 'rereview').&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Update (beside Metaprogramming in dynamically typed languages)&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the rereview method.&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95589</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95589"/>
		<updated>2015-03-23T03:49:24Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Steps to verify changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores  ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct.&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Review done at --2013-03-01 23:57:55 UTC&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the get_scores method.&lt;br /&gt;
&lt;br /&gt;
== rereview  ==&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
# Click on Assignments&lt;br /&gt;
# Click on Writing assignment 1b, Spring 2013&lt;br /&gt;
# Click on Others' Work&lt;br /&gt;
# Click on Update (beside Metaprogramming in dynamically typed languages)&lt;br /&gt;
&lt;br /&gt;
Successful loading of this page confirms the rereview method.&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95588</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95588"/>
		<updated>2015-03-23T03:42:50Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* get_scores &amp;amp; rereview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores &amp;amp; rereview ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct.&lt;br /&gt;
&amp;lt;br&amp;gt;Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&amp;lt;br&amp;gt;Both of these methods can be tested by following these steps:&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95587</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95587"/>
		<updated>2015-03-23T03:42:30Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* get_scores &amp;amp; rereview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores &amp;amp; rereview ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct.&lt;br /&gt;
&amp;lt;/br&amp;gt;Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&amp;lt;/br&amp;gt;Both of these methods can be tested by following these steps:&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95586</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95586"/>
		<updated>2015-03-23T03:42:11Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Action Allowed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
# Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores &amp;amp; rereview ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct.&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
Both of these methods can be tested by following these steps:&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95585</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95585"/>
		<updated>2015-03-23T03:41:49Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Steps to verify changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores &amp;amp; rereview ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct.&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
Both of these methods can be tested by following these steps:&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95584</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95584"/>
		<updated>2015-03-23T03:40:41Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* get_scores */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
== get_scores &amp;amp; rereview ==&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
==== rereview ====&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95583</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95583"/>
		<updated>2015-03-23T03:40:13Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Not Allowed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
===Not Allowed===&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
==== get_scores ====&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
==== rereview ====&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95582</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95582"/>
		<updated>2015-03-23T03:39:52Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Allowed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
===Allowed===&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
==Not Allowed==&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
=== get_scores ===&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
=== rereview ===&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95581</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95581"/>
		<updated>2015-03-23T03:39:41Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Action Allowed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
==Action Allowed==&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
==Allowed==&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
==Not Allowed==&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
=== get_scores ===&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
=== rereview ===&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:ActionallowedPass.png&amp;diff=95580</id>
		<title>File:ActionallowedPass.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:ActionallowedPass.png&amp;diff=95580"/>
		<updated>2015-03-23T03:08:24Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95579</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95579"/>
		<updated>2015-03-23T03:08:02Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Action Allowed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
===Action Allowed===&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
==Allowed==&lt;br /&gt;
Log into the application with the user having a student's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user5072, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedPass.png]]&lt;br /&gt;
&lt;br /&gt;
==Not Allowed==&lt;br /&gt;
Log into the application with the user having an instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Click on Assignments, and you should see the following:&lt;br /&gt;
&lt;br /&gt;
[[File:actionallowedFail.png]]&lt;br /&gt;
&lt;br /&gt;
=== get_scores ===&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
=== rereview ===&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:ActionallowedFail.png&amp;diff=95578</id>
		<title>File:ActionallowedFail.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:ActionallowedFail.png&amp;diff=95578"/>
		<updated>2015-03-23T03:04:39Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95577</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95577"/>
		<updated>2015-03-23T02:56:02Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Re-factored Code Cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code =&lt;br /&gt;
&lt;br /&gt;
==Removing duplicate methods==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving code to the proper place==&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Moving get_scores to the Response Model==&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
===Action Allowed===&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Go to Manage -&amp;gt; Assignments and expand the assignments section. &lt;br /&gt;
&lt;br /&gt;
4. Click on topics tab.&lt;br /&gt;
&lt;br /&gt;
[[File:Topics tab.png]]&lt;br /&gt;
&lt;br /&gt;
=== get_scores ===&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
=== rereview ===&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95576</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95576"/>
		<updated>2015-03-23T02:53:47Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving code to the proper place===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving get_scores to the Response Model===&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
===Action Allowed===&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Go to Manage -&amp;gt; Assignments and expand the assignments section. &lt;br /&gt;
&lt;br /&gt;
4. Click on topics tab.&lt;br /&gt;
&lt;br /&gt;
[[File:Topics tab.png]]&lt;br /&gt;
&lt;br /&gt;
=== get_scores ===&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
=== rereview ===&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95575</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95575"/>
		<updated>2015-03-23T02:53:03Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Action Allowed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving code to the proper place===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving get_scores to the Response Model===&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
===Action Allowed===&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having instructor's role (&amp;lt;b&amp;gt;User Id:&amp;lt;/b&amp;gt; user6, &amp;lt;b&amp;gt;Password:&amp;lt;/b&amp;gt; password)&lt;br /&gt;
&lt;br /&gt;
1. Go to Manage -&amp;gt; Assignments and expand the assignments section. &lt;br /&gt;
&lt;br /&gt;
4. Click on topics tab.&lt;br /&gt;
&lt;br /&gt;
[[File:Topics tab.png]]&lt;br /&gt;
&lt;br /&gt;
=== get_scores ===&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
=== rereview ===&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95574</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95574"/>
		<updated>2015-03-23T02:51:17Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Moving get_scores to the Response Model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving code to the proper place===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving get_scores to the Response Model===&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @question_type = []&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
        .where(&lt;br /&gt;
          response_id: @response.id,&lt;br /&gt;
          question_id:  question.id&lt;br /&gt;
        ).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
     @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
===Action Allowed===&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having instructor's role (user6, password)&lt;br /&gt;
&lt;br /&gt;
1. Go to Manage -&amp;gt; Assignments and expand the assignments section. &lt;br /&gt;
&lt;br /&gt;
4. Click on topics tab.&lt;br /&gt;
&lt;br /&gt;
[[File:Topics tab.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_scores ===&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
=== rereview ===&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95573</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95573"/>
		<updated>2015-03-23T02:49:28Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Moving code to the proper place */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving code to the proper place===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were removed (action_allowed? gets called automatically).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if Response.where(id: params[:id]).empty?&lt;br /&gt;
      true&lt;br /&gt;
    elsif&lt;br /&gt;
    response = Response.find(params[:id])&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving get_scores to the Response Model===&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
-    @review_scores = []&lt;br /&gt;
-    @question_type = []&lt;br /&gt;
-    @questions.each do |question|&lt;br /&gt;
-      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
-        .where(&lt;br /&gt;
-          response_id: @response.id,&lt;br /&gt;
-          question_id:  question.id&lt;br /&gt;
-        ).first&lt;br /&gt;
-      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
-    end&lt;br /&gt;
-  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
-    return if action_allowed?(@response)&lt;br /&gt;
+    #return if action_allowed?(@response)&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
-    get_scores(@response, @questions)&lt;br /&gt;
+    @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
===Action Allowed===&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having instructor's role (user6, password)&lt;br /&gt;
&lt;br /&gt;
1. Go to Manage -&amp;gt; Assignments and expand the assignments section. &lt;br /&gt;
&lt;br /&gt;
4. Click on topics tab.&lt;br /&gt;
&lt;br /&gt;
[[File:Topics tab.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_scores ===&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
=== rereview ===&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95572</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95572"/>
		<updated>2015-03-23T02:46:27Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Response Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving code to the proper place===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were changed to action_allowed? (left out of wiki for brevity).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving get_scores to the Response Model===&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
-    @review_scores = []&lt;br /&gt;
-    @question_type = []&lt;br /&gt;
-    @questions.each do |question|&lt;br /&gt;
-      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
-        .where(&lt;br /&gt;
-          response_id: @response.id,&lt;br /&gt;
-          question_id:  question.id&lt;br /&gt;
-        ).first&lt;br /&gt;
-      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
-    end&lt;br /&gt;
-  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
-    return if action_allowed?(@response)&lt;br /&gt;
+    #return if action_allowed?(@response)&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
-    get_scores(@response, @questions)&lt;br /&gt;
+    @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
===Action Allowed===&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having instructor's role (user6, password)&lt;br /&gt;
&lt;br /&gt;
1. Go to Manage -&amp;gt; Assignments and expand the assignments section. &lt;br /&gt;
&lt;br /&gt;
4. Click on topics tab.&lt;br /&gt;
&lt;br /&gt;
[[File:Topics tab.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_scores ===&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
=== rereview ===&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95571</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95571"/>
		<updated>2015-03-23T02:45:38Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Response Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and deleted all of the previous references (action_allowed? gets called automatically)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| rereview&lt;br /&gt;
| Moved logic for sorting response versions, and for getting the latest response to their own methods&lt;br /&gt;
| The rereview method was becoming too large and confusing&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|-&lt;br /&gt;
| get_scores&lt;br /&gt;
| Moved from controller (response_controller.rb) to model (response.rb)&lt;br /&gt;
| The functionality in get_scores makes more sense to be implemented in the Model rather than in the controller&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving code to the proper place===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were changed to action_allowed? (left out of wiki for brevity).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving get_scores to the Response Model===&lt;br /&gt;
The get_scores method was being implemented in the controller. Its function fits better in the model.&lt;br /&gt;
As such, the method was moved and changed to retain the functionality of code that uses it. Since the variables it requires were no longer in scope, they're passed in as arguments. Also due to scope, the result has to be explicitly returned.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores&lt;br /&gt;
-    @review_scores = []&lt;br /&gt;
-    @question_type = []&lt;br /&gt;
-    @questions.each do |question|&lt;br /&gt;
-      @review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
-        .where(&lt;br /&gt;
-          response_id: @response.id,&lt;br /&gt;
-          question_id:  question.id&lt;br /&gt;
-        ).first&lt;br /&gt;
-      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
-    end&lt;br /&gt;
-  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
In response.rb&lt;br /&gt;
&lt;br /&gt;
def get_scores(response, questions)&lt;br /&gt;
    review_scores = []&lt;br /&gt;
    question_type = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      review_scores &amp;lt;&amp;lt; Score&lt;br /&gt;
                            .where(&lt;br /&gt;
                                response_id: response.id,&lt;br /&gt;
                                question_id:  question.id&lt;br /&gt;
                            ).first&lt;br /&gt;
      question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
      question_type&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In response_controller.rb&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
     @response = Response.find(params[:id])&lt;br /&gt;
-    return if action_allowed?(@response)&lt;br /&gt;
+    #return if action_allowed?(@response)&lt;br /&gt;
     @map = @response.map&lt;br /&gt;
     get_content&lt;br /&gt;
-    get_scores(@response, @questions)&lt;br /&gt;
+    @question_type = @response.get_scores(@response, @questions)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;br /&gt;
&lt;br /&gt;
===Action Allowed===&lt;br /&gt;
Action allowed is called before every method call to confirm whether or not the currently logged in user has the required privileges to complete the requested action.&lt;br /&gt;
To test the functionality of this method one has to attempt to complete an action that they have privileges to complete, and confirm that they're allowed to complete it. One also has to attempt to complete an action that they don't have the privileges to complete, and confirm that they're not allowed to complete it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Log into the application with the user having instructor's role (user6, password)&lt;br /&gt;
&lt;br /&gt;
1. Go to Manage -&amp;gt; Assignments and expand the assignments section. &lt;br /&gt;
&lt;br /&gt;
4. Click on topics tab.&lt;br /&gt;
&lt;br /&gt;
[[File:Topics tab.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_scores ===&lt;br /&gt;
Get scores is called anytime the scores for reviews are shown. Given that, the way to test its correct functionality is to navigate to a completed review and make sure the scores are shown and are correct&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;br /&gt;
&lt;br /&gt;
=== rereview ===&lt;br /&gt;
Rereview manages the versioning of multiple reviews for the same assignment. To test the correct functionality of review, one should attempt to update a review ( i.e. 'rereview' )&lt;br /&gt;
&lt;br /&gt;
ADD STEPS HERE&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95001</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95001"/>
		<updated>2015-03-19T04:02:45Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Moving code to the proper place */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving code to the proper place===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method. Moreover, once this code was moved to the action_allowed? method, all of the references to redirect_when_disallowed were changed to action_allowed? (left out of wiki for brevity).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95000</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=95000"/>
		<updated>2015-03-19T03:59:45Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving code to the proper place===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Steps to verify changes=&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94999</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94999"/>
		<updated>2015-03-19T03:57:08Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Moving code to the proper place */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving code to the proper place===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    current_user&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
def redirect_when_disallowed(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?(response)&lt;br /&gt;
    # For author feedback, participants need to be able to read feedback submitted by other teammates.&lt;br /&gt;
    # If response is anything but author feedback, only the person who wrote feedback should be able to see it.&lt;br /&gt;
    if response.map.read_attribute(:type) == 'FeedbackResponseMap' &amp;amp;&amp;amp; response.map.assignment.team_assignment?&lt;br /&gt;
      team = response.map.reviewer.team&lt;br /&gt;
      unless team.has_user session[:user]&lt;br /&gt;
        redirect_to '/denied?reason=You are not on the team that wrote this feedback'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
      response.map.read_attribute(:type)&lt;br /&gt;
    end&lt;br /&gt;
    !current_user_id?(response.map.reviewer.user_id)&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94998</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94998"/>
		<updated>2015-03-19T03:53:35Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Removing duplicate methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Moving code to the proper place===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, in doing so, there needs to be some sort of authentication, and the proper place for that is in the action_allowed? method, however the un-refactored code did in the redirect_when_disallowed method.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94997</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94997"/>
		<updated>2015-03-19T03:47:40Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Removing duplicate methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:bottom;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94996</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94996"/>
		<updated>2015-03-19T03:47:10Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Removing duplicate methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, &lt;br /&gt;
                                         :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94995</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94995"/>
		<updated>2015-03-19T03:42:17Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Removing duplicate methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! |Before Changes&lt;br /&gt;
! |After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94994</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94994"/>
		<updated>2015-03-19T03:41:39Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Removing duplicate methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:45%;&amp;quot;|Before Changes&lt;br /&gt;
! style=&amp;quot;width:45%;&amp;quot;|After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94993</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94993"/>
		<updated>2015-03-19T03:39:41Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Removing duplicate methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, and the functionality changed over time, causing two new_feedback and view methods to be created; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:50%;&amp;quot;|Before Changes&lt;br /&gt;
! style=&amp;quot;width:50%;&amp;quot;|After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if redirect_when_disallowed(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    @review_scores = Array.new&lt;br /&gt;
    @question_type = Array.new&lt;br /&gt;
    @questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Score.where(response_id: @map.response_id, question_id:  question.id).first&lt;br /&gt;
      @question_type &amp;lt;&amp;lt; QuestionType.find_by_question_id(question.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def view&lt;br /&gt;
    @response = Response.find(params[:id])&lt;br /&gt;
    return if action_allowed?(@response)&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    get_content&lt;br /&gt;
    get_scores(@response, @questions)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94992</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94992"/>
		<updated>2015-03-19T03:36:43Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Removing duplicate methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, therefore it needs edit and view methods; however the functionality changed over time, causing two edit and view methods to be created, as well as new_feedback; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:50%;&amp;quot;|Before Changes&lt;br /&gt;
! style=&amp;quot;width:50%;&amp;quot;|After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.map_id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
def new_feedback&lt;br /&gt;
    review = Response.find(params[:id])&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id:  review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id:  reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        #if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(:reviewed_object_id =&amp;gt; review.id, :reviewer_id =&amp;gt; reviewer.id, :reviewee_id =&amp;gt; review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to :action =&amp;gt; 'new', :id =&amp;gt; map.id, :return =&amp;gt; &amp;quot;feedback&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to :back&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94991</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94991"/>
		<updated>2015-03-19T03:34:40Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Removing duplicate methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, therefore it needs edit and view methods; however the functionality changed over time, causing two edit and view methods to be created, as well as new_feedback; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:50%;&amp;quot;|Before Changes&lt;br /&gt;
! style=&amp;quot;width:50%;&amp;quot;|After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94990</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94990"/>
		<updated>2015-03-19T03:34:10Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Re-factored Code Cases =&lt;br /&gt;
&lt;br /&gt;
== Case 1 : Refactoring the ResponseController ==&lt;br /&gt;
&lt;br /&gt;
===Removing duplicate methods===&lt;br /&gt;
The ResponseController allows the user to create and edit responses to questionnaires, therefore it needs edit and view methods; however the functionality changed over time, causing two edit and view methods to be created, as well as new_feedback; the oldest of which doesn't get called anymore.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Before Changes&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|After Changes &lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94989</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94989"/>
		<updated>2015-03-19T03:15:43Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Response Model==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94988</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94988"/>
		<updated>2015-03-19T03:13:12Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Response Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Views==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:18%;&amp;quot;|View Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
sign_up_sheet/_add_signup_topcis&lt;br /&gt;
| Fixed title&lt;br /&gt;
| The page title displayed for an instructor was &amp;quot;Sign-up sheet for ... &amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Commented out View/Manage bookmark links&lt;br /&gt;
| These links were broken, and according to existing code were not meant for the instructor view.&lt;br /&gt;
|-&lt;br /&gt;
| Added variable initialization for @sign_up_topics&lt;br /&gt;
| The variable was referenced further on in the view, which was causing an 'nil value' error&lt;br /&gt;
|-&lt;br /&gt;
| Fixed flash message rendering for new topic creation&lt;br /&gt;
| The flash message was rendering incorrectly with HTML tags visible on the web page&lt;br /&gt;
|-&lt;br /&gt;
| Added full path names to partial names&lt;br /&gt;
| The shared partials were also being used by views in the Assignments controller, so full paths were needed&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_add_topics&lt;br /&gt;
| Added separation between the Import Topics and Manage Bookmarks links&lt;br /&gt;
| The two links were clumped together and it was difficult to distinguish between them&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_actions&lt;br /&gt;
| Replaced rendering of the reserve_topic partial with the _all_actions partial&lt;br /&gt;
| The reserve_topic partial is no longer being used and is replaced by the newly created _all_actions partial&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_all_actions&lt;br /&gt;
| Created this new partial&lt;br /&gt;
| We created the _all_actions partial to conditionally render the &amp;quot;Actions&amp;quot; table field for both instructors and students. This now also includes working links through which instructors or administrators can edit or delete topics.&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_table_line&lt;br /&gt;
| Gave edit/delete rights to Super Admin&lt;br /&gt;
| The Super-Administrator user wasn't included in the list of users with these permissions&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/edit&lt;br /&gt;
| Modified title and included @assignment_id variable to be passed as a parameter variable to the update action&lt;br /&gt;
| The view was initially trying to access the params[:assignment_id] variable which was not getting initialized&lt;br /&gt;
|-&lt;br /&gt;
| assignments/edit&lt;br /&gt;
| Changed the partial rendered to /sign_up_sheet/add_signup_topcis.html&lt;br /&gt;
| The assignments/edit/add_signup_topics partial (with duplicated code) was otherwise being rendered&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94987</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94987"/>
		<updated>2015-03-19T03:12:54Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Response Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references |&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|-&lt;br /&gt;
| action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Views==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:18%;&amp;quot;|View Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
sign_up_sheet/_add_signup_topcis&lt;br /&gt;
| Fixed title&lt;br /&gt;
| The page title displayed for an instructor was &amp;quot;Sign-up sheet for ... &amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Commented out View/Manage bookmark links&lt;br /&gt;
| These links were broken, and according to existing code were not meant for the instructor view.&lt;br /&gt;
|-&lt;br /&gt;
| Added variable initialization for @sign_up_topics&lt;br /&gt;
| The variable was referenced further on in the view, which was causing an 'nil value' error&lt;br /&gt;
|-&lt;br /&gt;
| Fixed flash message rendering for new topic creation&lt;br /&gt;
| The flash message was rendering incorrectly with HTML tags visible on the web page&lt;br /&gt;
|-&lt;br /&gt;
| Added full path names to partial names&lt;br /&gt;
| The shared partials were also being used by views in the Assignments controller, so full paths were needed&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_add_topics&lt;br /&gt;
| Added separation between the Import Topics and Manage Bookmarks links&lt;br /&gt;
| The two links were clumped together and it was difficult to distinguish between them&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_actions&lt;br /&gt;
| Replaced rendering of the reserve_topic partial with the _all_actions partial&lt;br /&gt;
| The reserve_topic partial is no longer being used and is replaced by the newly created _all_actions partial&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_all_actions&lt;br /&gt;
| Created this new partial&lt;br /&gt;
| We created the _all_actions partial to conditionally render the &amp;quot;Actions&amp;quot; table field for both instructors and students. This now also includes working links through which instructors or administrators can edit or delete topics.&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_table_line&lt;br /&gt;
| Gave edit/delete rights to Super Admin&lt;br /&gt;
| The Super-Administrator user wasn't included in the list of users with these permissions&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/edit&lt;br /&gt;
| Modified title and included @assignment_id variable to be passed as a parameter variable to the update action&lt;br /&gt;
| The view was initially trying to access the params[:assignment_id] variable which was not getting initialized&lt;br /&gt;
|-&lt;br /&gt;
| assignments/edit&lt;br /&gt;
| Changed the partial rendered to /sign_up_sheet/add_signup_topcis.html&lt;br /&gt;
| The assignments/edit/add_signup_topics partial (with duplicated code) was otherwise being rendered&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94979</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94979"/>
		<updated>2015-03-19T02:58:32Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Response Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| redirect_when_disallowed &amp;amp; action_allowed?&lt;br /&gt;
| Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Views==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:18%;&amp;quot;|View Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
sign_up_sheet/_add_signup_topcis&lt;br /&gt;
| Fixed title&lt;br /&gt;
| The page title displayed for an instructor was &amp;quot;Sign-up sheet for ... &amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Commented out View/Manage bookmark links&lt;br /&gt;
| These links were broken, and according to existing code were not meant for the instructor view.&lt;br /&gt;
|-&lt;br /&gt;
| Added variable initialization for @sign_up_topics&lt;br /&gt;
| The variable was referenced further on in the view, which was causing an 'nil value' error&lt;br /&gt;
|-&lt;br /&gt;
| Fixed flash message rendering for new topic creation&lt;br /&gt;
| The flash message was rendering incorrectly with HTML tags visible on the web page&lt;br /&gt;
|-&lt;br /&gt;
| Added full path names to partial names&lt;br /&gt;
| The shared partials were also being used by views in the Assignments controller, so full paths were needed&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_add_topics&lt;br /&gt;
| Added separation between the Import Topics and Manage Bookmarks links&lt;br /&gt;
| The two links were clumped together and it was difficult to distinguish between them&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_actions&lt;br /&gt;
| Replaced rendering of the reserve_topic partial with the _all_actions partial&lt;br /&gt;
| The reserve_topic partial is no longer being used and is replaced by the newly created _all_actions partial&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_all_actions&lt;br /&gt;
| Created this new partial&lt;br /&gt;
| We created the _all_actions partial to conditionally render the &amp;quot;Actions&amp;quot; table field for both instructors and students. This now also includes working links through which instructors or administrators can edit or delete topics.&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_table_line&lt;br /&gt;
| Gave edit/delete rights to Super Admin&lt;br /&gt;
| The Super-Administrator user wasn't included in the list of users with these permissions&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/edit&lt;br /&gt;
| Modified title and included @assignment_id variable to be passed as a parameter variable to the update action&lt;br /&gt;
| The view was initially trying to access the params[:assignment_id] variable which was not getting initialized&lt;br /&gt;
|-&lt;br /&gt;
| assignments/edit&lt;br /&gt;
| Changed the partial rendered to /sign_up_sheet/add_signup_topcis.html&lt;br /&gt;
| The assignments/edit/add_signup_topics partial (with duplicated code) was otherwise being rendered&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94978</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94978"/>
		<updated>2015-03-19T02:58:07Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Response Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
-&lt;br /&gt;
| redirect_when_disallowed &amp;amp; action_allowed?&lt;br /&gt;
| Moved all of the code from redirect_when_disallowed to action_allowed and changed all of the references&lt;br /&gt;
| Authorization to perform actions wasn't being performed correctly, it is supposed to be done through action_allowed?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Views==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:18%;&amp;quot;|View Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
sign_up_sheet/_add_signup_topcis&lt;br /&gt;
| Fixed title&lt;br /&gt;
| The page title displayed for an instructor was &amp;quot;Sign-up sheet for ... &amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Commented out View/Manage bookmark links&lt;br /&gt;
| These links were broken, and according to existing code were not meant for the instructor view.&lt;br /&gt;
|-&lt;br /&gt;
| Added variable initialization for @sign_up_topics&lt;br /&gt;
| The variable was referenced further on in the view, which was causing an 'nil value' error&lt;br /&gt;
|-&lt;br /&gt;
| Fixed flash message rendering for new topic creation&lt;br /&gt;
| The flash message was rendering incorrectly with HTML tags visible on the web page&lt;br /&gt;
|-&lt;br /&gt;
| Added full path names to partial names&lt;br /&gt;
| The shared partials were also being used by views in the Assignments controller, so full paths were needed&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_add_topics&lt;br /&gt;
| Added separation between the Import Topics and Manage Bookmarks links&lt;br /&gt;
| The two links were clumped together and it was difficult to distinguish between them&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_actions&lt;br /&gt;
| Replaced rendering of the reserve_topic partial with the _all_actions partial&lt;br /&gt;
| The reserve_topic partial is no longer being used and is replaced by the newly created _all_actions partial&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_all_actions&lt;br /&gt;
| Created this new partial&lt;br /&gt;
| We created the _all_actions partial to conditionally render the &amp;quot;Actions&amp;quot; table field for both instructors and students. This now also includes working links through which instructors or administrators can edit or delete topics.&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_table_line&lt;br /&gt;
| Gave edit/delete rights to Super Admin&lt;br /&gt;
| The Super-Administrator user wasn't included in the list of users with these permissions&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/edit&lt;br /&gt;
| Modified title and included @assignment_id variable to be passed as a parameter variable to the update action&lt;br /&gt;
| The view was initially trying to access the params[:assignment_id] variable which was not getting initialized&lt;br /&gt;
|-&lt;br /&gt;
| assignments/edit&lt;br /&gt;
| Changed the partial rendered to /sign_up_sheet/add_signup_topcis.html&lt;br /&gt;
| The assignments/edit/add_signup_topics partial (with duplicated code) was otherwise being rendered&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94969</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94969"/>
		<updated>2015-03-19T02:53:16Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Response Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| view&lt;br /&gt;
| Deleted the old view method&lt;br /&gt;
| The old view method was not getting called due to ruby rules&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Views==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:18%;&amp;quot;|View Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
sign_up_sheet/_add_signup_topcis&lt;br /&gt;
| Fixed title&lt;br /&gt;
| The page title displayed for an instructor was &amp;quot;Sign-up sheet for ... &amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Commented out View/Manage bookmark links&lt;br /&gt;
| These links were broken, and according to existing code were not meant for the instructor view.&lt;br /&gt;
|-&lt;br /&gt;
| Added variable initialization for @sign_up_topics&lt;br /&gt;
| The variable was referenced further on in the view, which was causing an 'nil value' error&lt;br /&gt;
|-&lt;br /&gt;
| Fixed flash message rendering for new topic creation&lt;br /&gt;
| The flash message was rendering incorrectly with HTML tags visible on the web page&lt;br /&gt;
|-&lt;br /&gt;
| Added full path names to partial names&lt;br /&gt;
| The shared partials were also being used by views in the Assignments controller, so full paths were needed&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_add_topics&lt;br /&gt;
| Added separation between the Import Topics and Manage Bookmarks links&lt;br /&gt;
| The two links were clumped together and it was difficult to distinguish between them&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_actions&lt;br /&gt;
| Replaced rendering of the reserve_topic partial with the _all_actions partial&lt;br /&gt;
| The reserve_topic partial is no longer being used and is replaced by the newly created _all_actions partial&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_all_actions&lt;br /&gt;
| Created this new partial&lt;br /&gt;
| We created the _all_actions partial to conditionally render the &amp;quot;Actions&amp;quot; table field for both instructors and students. This now also includes working links through which instructors or administrators can edit or delete topics.&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_table_line&lt;br /&gt;
| Gave edit/delete rights to Super Admin&lt;br /&gt;
| The Super-Administrator user wasn't included in the list of users with these permissions&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/edit&lt;br /&gt;
| Modified title and included @assignment_id variable to be passed as a parameter variable to the update action&lt;br /&gt;
| The view was initially trying to access the params[:assignment_id] variable which was not getting initialized&lt;br /&gt;
|-&lt;br /&gt;
| assignments/edit&lt;br /&gt;
| Changed the partial rendered to /sign_up_sheet/add_signup_topcis.html&lt;br /&gt;
| The assignments/edit/add_signup_topics partial (with duplicated code) was otherwise being rendered&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94967</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94967"/>
		<updated>2015-03-19T02:52:08Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Response Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Deleted the old edit method&lt;br /&gt;
| The old edit method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| new_feedback&lt;br /&gt;
| Deleted the old new_feedback method&lt;br /&gt;
| The old new_feedback method was not getting called due to ruby rules&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
destroy&lt;br /&gt;
| Renamed the 'delete' method to 'destroy'&lt;br /&gt;
| This was done for better Rails 4 routing compatibility&lt;br /&gt;
|-&lt;br /&gt;
| Initialized the assignment_id parameter&lt;br /&gt;
| This is used further on and is not passed from the link URL&lt;br /&gt;
|-&lt;br /&gt;
| Fixed redirection after topic deletion to Topics tab&lt;br /&gt;
| Once a topic was successfully deleted, the view rendered was just a list of topics&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Views==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:18%;&amp;quot;|View Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
sign_up_sheet/_add_signup_topcis&lt;br /&gt;
| Fixed title&lt;br /&gt;
| The page title displayed for an instructor was &amp;quot;Sign-up sheet for ... &amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Commented out View/Manage bookmark links&lt;br /&gt;
| These links were broken, and according to existing code were not meant for the instructor view.&lt;br /&gt;
|-&lt;br /&gt;
| Added variable initialization for @sign_up_topics&lt;br /&gt;
| The variable was referenced further on in the view, which was causing an 'nil value' error&lt;br /&gt;
|-&lt;br /&gt;
| Fixed flash message rendering for new topic creation&lt;br /&gt;
| The flash message was rendering incorrectly with HTML tags visible on the web page&lt;br /&gt;
|-&lt;br /&gt;
| Added full path names to partial names&lt;br /&gt;
| The shared partials were also being used by views in the Assignments controller, so full paths were needed&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_add_topics&lt;br /&gt;
| Added separation between the Import Topics and Manage Bookmarks links&lt;br /&gt;
| The two links were clumped together and it was difficult to distinguish between them&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_actions&lt;br /&gt;
| Replaced rendering of the reserve_topic partial with the _all_actions partial&lt;br /&gt;
| The reserve_topic partial is no longer being used and is replaced by the newly created _all_actions partial&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_all_actions&lt;br /&gt;
| Created this new partial&lt;br /&gt;
| We created the _all_actions partial to conditionally render the &amp;quot;Actions&amp;quot; table field for both instructors and students. This now also includes working links through which instructors or administrators can edit or delete topics.&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_table_line&lt;br /&gt;
| Gave edit/delete rights to Super Admin&lt;br /&gt;
| The Super-Administrator user wasn't included in the list of users with these permissions&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/edit&lt;br /&gt;
| Modified title and included @assignment_id variable to be passed as a parameter variable to the update action&lt;br /&gt;
| The view was initially trying to access the params[:assignment_id] variable which was not getting initialized&lt;br /&gt;
|-&lt;br /&gt;
| assignments/edit&lt;br /&gt;
| Changed the partial rendered to /sign_up_sheet/add_signup_topcis.html&lt;br /&gt;
| The assignments/edit/add_signup_topics partial (with duplicated code) was otherwise being rendered&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94962</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94962"/>
		<updated>2015-03-19T02:49:17Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Response Controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| latestResponseVersion&lt;br /&gt;
| Changed name to previous_responses&lt;br /&gt;
| The name wasn't indicative of what the method did&lt;br /&gt;
|-&lt;br /&gt;
| update&lt;br /&gt;
| Fixed redirection after topic updation to Topics tab&lt;br /&gt;
| Once a topic was successfully edited, the view rendered was just a list of topics&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Initialized @assignment_id variable&lt;br /&gt;
| The variable is used in the edit view&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
destroy&lt;br /&gt;
| Renamed the 'delete' method to 'destroy'&lt;br /&gt;
| This was done for better Rails 4 routing compatibility&lt;br /&gt;
|-&lt;br /&gt;
| Initialized the assignment_id parameter&lt;br /&gt;
| This is used further on and is not passed from the link URL&lt;br /&gt;
|-&lt;br /&gt;
| Fixed redirection after topic deletion to Topics tab&lt;br /&gt;
| Once a topic was successfully deleted, the view rendered was just a list of topics&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Views==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:18%;&amp;quot;|View Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
sign_up_sheet/_add_signup_topcis&lt;br /&gt;
| Fixed title&lt;br /&gt;
| The page title displayed for an instructor was &amp;quot;Sign-up sheet for ... &amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Commented out View/Manage bookmark links&lt;br /&gt;
| These links were broken, and according to existing code were not meant for the instructor view.&lt;br /&gt;
|-&lt;br /&gt;
| Added variable initialization for @sign_up_topics&lt;br /&gt;
| The variable was referenced further on in the view, which was causing an 'nil value' error&lt;br /&gt;
|-&lt;br /&gt;
| Fixed flash message rendering for new topic creation&lt;br /&gt;
| The flash message was rendering incorrectly with HTML tags visible on the web page&lt;br /&gt;
|-&lt;br /&gt;
| Added full path names to partial names&lt;br /&gt;
| The shared partials were also being used by views in the Assignments controller, so full paths were needed&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_add_topics&lt;br /&gt;
| Added separation between the Import Topics and Manage Bookmarks links&lt;br /&gt;
| The two links were clumped together and it was difficult to distinguish between them&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_actions&lt;br /&gt;
| Replaced rendering of the reserve_topic partial with the _all_actions partial&lt;br /&gt;
| The reserve_topic partial is no longer being used and is replaced by the newly created _all_actions partial&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_all_actions&lt;br /&gt;
| Created this new partial&lt;br /&gt;
| We created the _all_actions partial to conditionally render the &amp;quot;Actions&amp;quot; table field for both instructors and students. This now also includes working links through which instructors or administrators can edit or delete topics.&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_table_line&lt;br /&gt;
| Gave edit/delete rights to Super Admin&lt;br /&gt;
| The Super-Administrator user wasn't included in the list of users with these permissions&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/edit&lt;br /&gt;
| Modified title and included @assignment_id variable to be passed as a parameter variable to the update action&lt;br /&gt;
| The view was initially trying to access the params[:assignment_id] variable which was not getting initialized&lt;br /&gt;
|-&lt;br /&gt;
| assignments/edit&lt;br /&gt;
| Changed the partial rendered to /sign_up_sheet/add_signup_topcis.html&lt;br /&gt;
| The assignments/edit/add_signup_topics partial (with duplicated code) was otherwise being rendered&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94958</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94958"/>
		<updated>2015-03-19T02:46:36Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==Response Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| create&lt;br /&gt;
| Fixed redirection after topic creation to Topics tab&lt;br /&gt;
| On successful creation of a topic, the action was merely redirecting to the assignments/edit view&lt;br /&gt;
|-&lt;br /&gt;
| update&lt;br /&gt;
| Fixed redirection after topic updation to Topics tab&lt;br /&gt;
| Once a topic was successfully edited, the view rendered was just a list of topics&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Initialized @assignment_id variable&lt;br /&gt;
| The variable is used in the edit view&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
destroy&lt;br /&gt;
| Renamed the 'delete' method to 'destroy'&lt;br /&gt;
| This was done for better Rails 4 routing compatibility&lt;br /&gt;
|-&lt;br /&gt;
| Initialized the assignment_id parameter&lt;br /&gt;
| This is used further on and is not passed from the link URL&lt;br /&gt;
|-&lt;br /&gt;
| Fixed redirection after topic deletion to Topics tab&lt;br /&gt;
| Once a topic was successfully deleted, the view rendered was just a list of topics&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Views==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:18%;&amp;quot;|View Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
sign_up_sheet/_add_signup_topcis&lt;br /&gt;
| Fixed title&lt;br /&gt;
| The page title displayed for an instructor was &amp;quot;Sign-up sheet for ... &amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Commented out View/Manage bookmark links&lt;br /&gt;
| These links were broken, and according to existing code were not meant for the instructor view.&lt;br /&gt;
|-&lt;br /&gt;
| Added variable initialization for @sign_up_topics&lt;br /&gt;
| The variable was referenced further on in the view, which was causing an 'nil value' error&lt;br /&gt;
|-&lt;br /&gt;
| Fixed flash message rendering for new topic creation&lt;br /&gt;
| The flash message was rendering incorrectly with HTML tags visible on the web page&lt;br /&gt;
|-&lt;br /&gt;
| Added full path names to partial names&lt;br /&gt;
| The shared partials were also being used by views in the Assignments controller, so full paths were needed&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_add_topics&lt;br /&gt;
| Added separation between the Import Topics and Manage Bookmarks links&lt;br /&gt;
| The two links were clumped together and it was difficult to distinguish between them&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_actions&lt;br /&gt;
| Replaced rendering of the reserve_topic partial with the _all_actions partial&lt;br /&gt;
| The reserve_topic partial is no longer being used and is replaced by the newly created _all_actions partial&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_all_actions&lt;br /&gt;
| Created this new partial&lt;br /&gt;
| We created the _all_actions partial to conditionally render the &amp;quot;Actions&amp;quot; table field for both instructors and students. This now also includes working links through which instructors or administrators can edit or delete topics.&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_table_line&lt;br /&gt;
| Gave edit/delete rights to Super Admin&lt;br /&gt;
| The Super-Administrator user wasn't included in the list of users with these permissions&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/edit&lt;br /&gt;
| Modified title and included @assignment_id variable to be passed as a parameter variable to the update action&lt;br /&gt;
| The view was initially trying to access the params[:assignment_id] variable which was not getting initialized&lt;br /&gt;
|-&lt;br /&gt;
| assignments/edit&lt;br /&gt;
| Changed the partial rendered to /sign_up_sheet/add_signup_topcis.html&lt;br /&gt;
| The assignments/edit/add_signup_topics partial (with duplicated code) was otherwise being rendered&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94957</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94957"/>
		<updated>2015-03-19T02:45:49Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
=Changes Made=&lt;br /&gt;
&lt;br /&gt;
==SignupSheet Controller==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:13%;&amp;quot;|Method Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| create&lt;br /&gt;
| Fixed redirection after topic creation to Topics tab&lt;br /&gt;
| On successful creation of a topic, the action was merely redirecting to the assignments/edit view&lt;br /&gt;
|-&lt;br /&gt;
| update&lt;br /&gt;
| Fixed redirection after topic updation to Topics tab&lt;br /&gt;
| Once a topic was successfully edited, the view rendered was just a list of topics&lt;br /&gt;
|-&lt;br /&gt;
| edit&lt;br /&gt;
| Initialized @assignment_id variable&lt;br /&gt;
| The variable is used in the edit view&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
destroy&lt;br /&gt;
| Renamed the 'delete' method to 'destroy'&lt;br /&gt;
| This was done for better Rails 4 routing compatibility&lt;br /&gt;
|-&lt;br /&gt;
| Initialized the assignment_id parameter&lt;br /&gt;
| This is used further on and is not passed from the link URL&lt;br /&gt;
|-&lt;br /&gt;
| Fixed redirection after topic deletion to Topics tab&lt;br /&gt;
| Once a topic was successfully deleted, the view rendered was just a list of topics&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Views==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:18%;&amp;quot;|View Name&lt;br /&gt;
! style=&amp;quot;width:33%;&amp;quot;|Changes Made &lt;br /&gt;
! style=&amp;quot;width:43%;&amp;quot;|Reason For Change&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; valign=&amp;quot;middle&amp;quot; |&lt;br /&gt;
sign_up_sheet/_add_signup_topcis&lt;br /&gt;
| Fixed title&lt;br /&gt;
| The page title displayed for an instructor was &amp;quot;Sign-up sheet for ... &amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Commented out View/Manage bookmark links&lt;br /&gt;
| These links were broken, and according to existing code were not meant for the instructor view.&lt;br /&gt;
|-&lt;br /&gt;
| Added variable initialization for @sign_up_topics&lt;br /&gt;
| The variable was referenced further on in the view, which was causing an 'nil value' error&lt;br /&gt;
|-&lt;br /&gt;
| Fixed flash message rendering for new topic creation&lt;br /&gt;
| The flash message was rendering incorrectly with HTML tags visible on the web page&lt;br /&gt;
|-&lt;br /&gt;
| Added full path names to partial names&lt;br /&gt;
| The shared partials were also being used by views in the Assignments controller, so full paths were needed&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_add_topics&lt;br /&gt;
| Added separation between the Import Topics and Manage Bookmarks links&lt;br /&gt;
| The two links were clumped together and it was difficult to distinguish between them&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_actions&lt;br /&gt;
| Replaced rendering of the reserve_topic partial with the _all_actions partial&lt;br /&gt;
| The reserve_topic partial is no longer being used and is replaced by the newly created _all_actions partial&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_all_actions&lt;br /&gt;
| Created this new partial&lt;br /&gt;
| We created the _all_actions partial to conditionally render the &amp;quot;Actions&amp;quot; table field for both instructors and students. This now also includes working links through which instructors or administrators can edit or delete topics.&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/_table_line&lt;br /&gt;
| Gave edit/delete rights to Super Admin&lt;br /&gt;
| The Super-Administrator user wasn't included in the list of users with these permissions&lt;br /&gt;
|-&lt;br /&gt;
| sign_up_sheet/edit&lt;br /&gt;
| Modified title and included @assignment_id variable to be passed as a parameter variable to the update action&lt;br /&gt;
| The view was initially trying to access the params[:assignment_id] variable which was not getting initialized&lt;br /&gt;
|-&lt;br /&gt;
| assignments/edit&lt;br /&gt;
| Changed the partial rendered to /sign_up_sheet/add_signup_topcis.html&lt;br /&gt;
| The assignments/edit/add_signup_topics partial (with duplicated code) was otherwise being rendered&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94951</id>
		<title>CSC/ECE 517 Fall 2014/oss E1508 MRS</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2014/oss_E1508_MRS&amp;diff=94951"/>
		<updated>2015-03-19T02:41:23Z</updated>

		<summary type="html">&lt;p&gt;Rlcoble: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E1508 Refactoring Response Controller'''&lt;br /&gt;
&lt;br /&gt;
This page provides a description of the Expertiza based OSS project. This project aimed at refactoring the ResponseController.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Problem Statement =&lt;br /&gt;
'''Classes involved:'''&lt;br /&gt;
 response_controller.rb&lt;br /&gt;
 response.rb&lt;br /&gt;
 '''???????'''&lt;br /&gt;
&lt;br /&gt;
'''What they do:'''&lt;br /&gt;
Allows the user to create and edit responses to questionnaires … such as performing a review, rating a teammate, or giving feedback to a reviewer.&lt;br /&gt;
&lt;br /&gt;
'''What's wrong with it:'''&lt;br /&gt;
* It doesn’t do authorization properly.&lt;br /&gt;
* It contains duplicated methods.&lt;br /&gt;
* Functionality that should be in models is incorporated into the controller.&lt;br /&gt;
&lt;br /&gt;
'''What needs to be done:'''&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;latestresponseversion&amp;lt;/font&amp;gt; seems misnamed.  It fetches all previous versions of a response (which is to say, all previous review versions by the current reviewer of the current author for the current assignment).&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;get_scores&amp;lt;/font&amp;gt; gets all the scores assigned in a particular response.  A “response” is created when someone submits a review, a partner evaluation, a survey, etc.&lt;br /&gt;
# The &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; method is 98 lines long.  Several parts of it should be turned into methods.  Sorting review versions is really not a controller responsibility; it would be better to do this in a model class (which class?)  Ditto for determining whether a review is current (i.e., was done during the current assignment phase).  This is a query that is made about a review (actually, about a response, which may be a review, author feedback, etc.).  It should be placed in the appropriate model class.&lt;br /&gt;
# &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt; contains special code to check whether an assignment is “Jen’s assignment”; this was the first assignment we ever created with a multipart rubric.  It was hard-coded into the system, rather than working on a rubric that was created in the normal way.  It is probably impossible to remove this code without breaking that assignment, but it should be done in a separate method, and commented appropriately as a kludge.&lt;br /&gt;
# Again in &amp;lt;font face=Courier New&amp;gt;rereview&amp;lt;/font&amp;gt;, creating a new version of a review is a model responsibility, and should be moved out of the controller.&lt;br /&gt;
# There are two (consecutive) copies of the &amp;lt;font face=Courier New&amp;gt;edit&amp;lt;/font&amp;gt; method.  The second appears to be the newer one, and, according to the rules for method definition, is the one that is currently in use.  The first should be removed.   Ditto for &amp;lt;font face=Courier New&amp;gt;new_feedback&amp;lt;/font&amp;gt; and &amp;lt;font face=Courier New&amp;gt;view&amp;lt;/font&amp;gt;--the 2nd version of each appears to be newer &amp;amp; should be kept.&lt;br /&gt;
# Authorization to perform actions is not checked correctly.  It is supposed to be done through the &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method at the beginning of the class definition.  Different authorization should be required for different operations.  For example, someone should be allowed to view a response if they wrote the response, or they are the person or on the team whose work the response applied to, or if they are an instructor or TA for the class.  The person who wrote a response should be allowed to edit it, but not the person/team who was being reviewed, nor the instructor or TA for the class. Currently, authorization is denied by the &amp;lt;font face=Courier New&amp;gt;redirect_when_disallowed&amp;lt;/font&amp;gt; method, which was an earlier, more error-prone way of controlling access.  It should go away, now that the class has an &amp;lt;font face=Courier New&amp;gt;action_allowed?&amp;lt;/font&amp;gt; method.&lt;/div&gt;</summary>
		<author><name>Rlcoble</name></author>
	</entry>
</feed>