<?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=Sstangad</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=Sstangad"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Sstangad"/>
	<updated>2026-06-01T12:14:32Z</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_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150399</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150399"/>
		<updated>2023-05-03T20:19:01Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Test Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated.&lt;br /&gt;
&lt;br /&gt;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project. Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File: ArchitectDiagram.png | 800px]]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' The BadgesController has been re-implemented in a more efficient and object-oriented manner by adhering to the RESTful API for the controller. The controller logic has been split into two separate parts: the Badge model and the BadgesController controller. Previously, all CRUD methods and dependent methods were contained in the same controller class, which went against the principles of the MVC pattern. As part of the changes, the dependent and validation methods have been relocated to the Badge.rb model class, which has made it much easier and more intuitive for coders to work with the code. These changes have already been implemented and are now in effect.&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
    render json: { badges: @badges }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def show&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
&lt;br /&gt;
    if @badge.save&lt;br /&gt;
      render json: { badge: @badge }, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      render json: { badge: @badge }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def destroy&lt;br /&gt;
    @badge.destroy&lt;br /&gt;
    render json: { message: &amp;quot;Badge was successfully destroyed.&amp;quot; }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name, :image_file)&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;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/blob/main/app/controllers/duties_controller.rb Here is the previous implementation of the duties_controller.rb]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The class diagram below explains how the classes and the objects interact with each other. Also, it gives a brief idea about the implementation of the operations implemented in the Controllers.&lt;br /&gt;
[[File: Duty 1.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Swagger UI'''&lt;br /&gt;
&lt;br /&gt;
As part of our testing process, we have implemented Swagger UI automated testing to thoroughly test the DutiesController and BadgesController, as well as the Duty and Badge model classes. Swagger UI is a tool that allows us to test each API endpoint by sending HTTP requests and receiving responses.&lt;br /&gt;
&lt;br /&gt;
To ensure that each endpoint is working correctly, we have created test cases for each route of the DutiesController and BadgesController. For each test case, we make a valid request with the correct parameters and verify that the expected response is obtained. This helps us ensure that each endpoint is capable of processing requests and returning the correct output.&lt;br /&gt;
&lt;br /&gt;
In addition to testing valid requests, we have also tested for invalid requests. This involves submitting requests with an incorrect number of parameters, invalid parameter types, and values that do not meet the validation requirements of the endpoint. When testing invalid requests, we expect the endpoint to return a status 422 Invalid Request as the response. By testing invalid requests, we can ensure that each endpoint is capable of handling unexpected inputs and responding appropriately.&lt;br /&gt;
&lt;br /&gt;
By employing Swagger UI automated testing, we have been able to thoroughly test each API endpoint and ensure that they are capable of handling both valid and invalid requests. This helps us ensure that our API functions as intended and that any issues are caught early in the development process.&lt;br /&gt;
Here are some snapshots of the API testing done using Swagger: &lt;br /&gt;
&lt;br /&gt;
[[ File: API screenshots.png | 850px ]]&lt;br /&gt;
&lt;br /&gt;
[[ File: APi screenshots1.png | 850px ]]&lt;br /&gt;
&lt;br /&gt;
[[ File: API screenshot2.png | 850px ]]&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
As part of our testing process, we have implemented RSpec test cases to thoroughly test our code base. Using RSpec allows us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we have the ability to write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By utilizing RSpec, we have greater confidence in the correctness of our code and can quickly identify any issues that may arise as changes are made. We have already employed RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
Specifically, for the BadgesController and DutiesController, we have written test cases to thoroughly test the CRUD operations and their associated functionalities. We have tested API functionalities by writing test cases for the get, patch, and post API calls. For example, we can write a test case to ensure that the controller behaves as intended when a user attempts to update a badge. This involves verifying that the update request is received by the controller, the badge is updated in the database with the correct information, and the updated badge is returned in the response. By writing test cases in this manner, we can ensure that our API functions as intended and any issues are caught early in the development process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150398</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150398"/>
		<updated>2023-05-03T20:14:41Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Test Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated.&lt;br /&gt;
&lt;br /&gt;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project. Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File: ArchitectDiagram.png | 800px]]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' The BadgesController has been re-implemented in a more efficient and object-oriented manner by adhering to the RESTful API for the controller. The controller logic has been split into two separate parts: the Badge model and the BadgesController controller. Previously, all CRUD methods and dependent methods were contained in the same controller class, which went against the principles of the MVC pattern. As part of the changes, the dependent and validation methods have been relocated to the Badge.rb model class, which has made it much easier and more intuitive for coders to work with the code. These changes have already been implemented and are now in effect.&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
    render json: { badges: @badges }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def show&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
&lt;br /&gt;
    if @badge.save&lt;br /&gt;
      render json: { badge: @badge }, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      render json: { badge: @badge }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def destroy&lt;br /&gt;
    @badge.destroy&lt;br /&gt;
    render json: { message: &amp;quot;Badge was successfully destroyed.&amp;quot; }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name, :image_file)&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;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/blob/main/app/controllers/duties_controller.rb Here is the previous implementation of the duties_controller.rb]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The class diagram below explains how the classes and the objects interact with each other. Also, it gives a brief idea about the implementation of the operations implemented in the Controllers.&lt;br /&gt;
[[File: Duty 1.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Swagger UI'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Swagger UI automated testing to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Swagger UI will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Here are some snapshots of the API testing done using Swagger: &lt;br /&gt;
&lt;br /&gt;
[[ File: API screenshots.png | 850px ]]&lt;br /&gt;
&lt;br /&gt;
[[ File: APi screenshots1.png | 850px ]]&lt;br /&gt;
&lt;br /&gt;
[[ File: API screenshot2.png | 850px ]]&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:API_screenshot2.png&amp;diff=150397</id>
		<title>File:API screenshot2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:API_screenshot2.png&amp;diff=150397"/>
		<updated>2023-05-03T20:10:30Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:APi_screenshots1.png&amp;diff=150396</id>
		<title>File:APi screenshots1.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:APi_screenshots1.png&amp;diff=150396"/>
		<updated>2023-05-03T20:09:58Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:API_screenshots.png&amp;diff=150395</id>
		<title>File:API screenshots.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:API_screenshots.png&amp;diff=150395"/>
		<updated>2023-05-03T20:09:32Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150394</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150394"/>
		<updated>2023-05-03T20:08:57Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Test Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated.&lt;br /&gt;
&lt;br /&gt;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project. Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File: ArchitectDiagram.png | 800px]]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' The BadgesController has been re-implemented in a more efficient and object-oriented manner by adhering to the RESTful API for the controller. The controller logic has been split into two separate parts: the Badge model and the BadgesController controller. Previously, all CRUD methods and dependent methods were contained in the same controller class, which went against the principles of the MVC pattern. As part of the changes, the dependent and validation methods have been relocated to the Badge.rb model class, which has made it much easier and more intuitive for coders to work with the code. These changes have already been implemented and are now in effect.&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
    render json: { badges: @badges }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def show&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
&lt;br /&gt;
    if @badge.save&lt;br /&gt;
      render json: { badge: @badge }, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      render json: { badge: @badge }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def destroy&lt;br /&gt;
    @badge.destroy&lt;br /&gt;
    render json: { message: &amp;quot;Badge was successfully destroyed.&amp;quot; }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name, :image_file)&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;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/blob/main/app/controllers/duties_controller.rb Here is the previous implementation of the duties_controller.rb]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The class diagram below explains how the classes and the objects interact with each other. Also, it gives a brief idea about the implementation of the operations implemented in the Controllers.&lt;br /&gt;
[[File: Duty 1.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Swagger UI'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Swagger UI automated testing to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Swagger UI will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Here are some snapshots of the API testing done using Swagger: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150393</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150393"/>
		<updated>2023-05-03T20:05:37Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Design and Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated.&lt;br /&gt;
&lt;br /&gt;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project. Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File: ArchitectDiagram.png | 800px]]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' The BadgesController has been re-implemented in a more efficient and object-oriented manner by adhering to the RESTful API for the controller. The controller logic has been split into two separate parts: the Badge model and the BadgesController controller. Previously, all CRUD methods and dependent methods were contained in the same controller class, which went against the principles of the MVC pattern. As part of the changes, the dependent and validation methods have been relocated to the Badge.rb model class, which has made it much easier and more intuitive for coders to work with the code. These changes have already been implemented and are now in effect.&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
    render json: { badges: @badges }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def show&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
&lt;br /&gt;
    if @badge.save&lt;br /&gt;
      render json: { badge: @badge }, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      render json: { badge: @badge }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def destroy&lt;br /&gt;
    @badge.destroy&lt;br /&gt;
    render json: { message: &amp;quot;Badge was successfully destroyed.&amp;quot; }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name, :image_file)&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;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/blob/main/app/controllers/duties_controller.rb Here is the previous implementation of the duties_controller.rb]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The class diagram below explains how the classes and the objects interact with each other. Also, it gives a brief idea about the implementation of the operations implemented in the Controllers.&lt;br /&gt;
[[File: Duty 1.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Swagger UI automated testing to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Swagger UI will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150392</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150392"/>
		<updated>2023-05-03T20:03:02Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Design and Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated.&lt;br /&gt;
&lt;br /&gt;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project. Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File: ArchitectDiagram.png | 800px]]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' The BadgesController has been re-implemented in a more efficient and object-oriented manner by adhering to the RESTful API for the controller. The controller logic has been split into two separate parts: the Badge model and the BadgesController controller. Previously, all CRUD methods and dependent methods were contained in the same controller class, which went against the principles of the MVC pattern. As part of the changes, the dependent and validation methods have been relocated to the Badge.rb model class, which has made it much easier and more intuitive for coders to work with the code. These changes have already been implemented and are now in effect.&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
    render json: { badges: @badges }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def show&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
&lt;br /&gt;
    if @badge.save&lt;br /&gt;
      render json: { badge: @badge }, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      render json: { badge: @badge }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def destroy&lt;br /&gt;
    @badge.destroy&lt;br /&gt;
    render json: { message: &amp;quot;Badge was successfully destroyed.&amp;quot; }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name, :image_file)&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;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class diagram below explains how the classes and the objects interact with each other. Also, it gives a brief idea about the implementation of the operations implemented in the Controllers.&lt;br /&gt;
[[File: Duty 1.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Swagger UI automated testing to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Swagger UI will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150391</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150391"/>
		<updated>2023-05-03T19:59:55Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Design and Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated.&lt;br /&gt;
&lt;br /&gt;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project. Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File: ArchitectDiagram.png | 800px]]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' The BadgesController has been re-implemented in a more efficient and object-oriented manner by adhering to the RESTful API for the controller. The controller logic has been split into two separate parts: the Badge model and the BadgesController controller. Previously, all CRUD methods and dependent methods were contained in the same controller class, which went against the principles of the MVC pattern. As part of the changes, the dependent and validation methods have been relocated to the Badge.rb model class, which has made it much easier and more intuitive for coders to work with the code. These changes have already been implemented and are now in effect.&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
    render json: { badges: @badges }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def show&lt;br /&gt;
    render json: { badge: @badge }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
&lt;br /&gt;
    if @badge.save&lt;br /&gt;
      render json: { badge: @badge }, status: :created&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      render json: { badge: @badge }, status: :ok&lt;br /&gt;
    else&lt;br /&gt;
      render json: { errors: @badge.errors.full_messages }, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def destroy&lt;br /&gt;
    @badge.destroy&lt;br /&gt;
    render json: { message: &amp;quot;Badge was successfully destroyed.&amp;quot; }, status: :ok&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name, :image_file)&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;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: Duty 1.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Swagger UI automated testing to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Swagger UI will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150132</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=150132"/>
		<updated>2023-04-25T03:31:24Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Test Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated.&lt;br /&gt;
&lt;br /&gt;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project. Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File: ArchitectDiagram.png | 800px]]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: Duty 1.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Swagger UI automated testing to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Swagger UI will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149707</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149707"/>
		<updated>2023-04-13T02:38:19Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Design and Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated.&lt;br /&gt;
&lt;br /&gt;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project. Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File: ArchitectDiagram.png | 800px]]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File: Duty 1.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149634</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149634"/>
		<updated>2023-04-13T00:47:16Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Design and Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated.&lt;br /&gt;
&lt;br /&gt;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project. Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File: ArchitectDiagram.png | 800px]]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:ArchitectDiagram.png&amp;diff=149633</id>
		<title>File:ArchitectDiagram.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:ArchitectDiagram.png&amp;diff=149633"/>
		<updated>2023-04-13T00:45:18Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149631</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149631"/>
		<updated>2023-04-13T00:44:02Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Design and Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&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;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project.Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File:Arch Diagram.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Arch_Diagram.png&amp;diff=149630</id>
		<title>File:Arch Diagram.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Arch_Diagram.png&amp;diff=149630"/>
		<updated>2023-04-13T00:43:23Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Architecture_Diagram.jpeg&amp;diff=149628</id>
		<title>File:Architecture Diagram.jpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Architecture_Diagram.jpeg&amp;diff=149628"/>
		<updated>2023-04-13T00:41:14Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149627</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149627"/>
		<updated>2023-04-13T00:40:45Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Design and Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&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;
The MVC architecture is well-suited for object-oriented principles-focused projects or applications because it follows the principles of separation of concerns, modularity, and extensibility. Separating the application into three distinct components, each with a specific responsibility, it allows for greater flexibility in making changes and adding new features without affecting the entire system. Furthermore, the MVC architecture promotes code reuse, since each component can be designed and tested independently. This results in cleaner, more maintainable code and can reduce the overall development time and cost of the project.Overall, the MVC architecture is an effective way to organize and structure complex object-oriented projects or applications, providing a solid foundation for software development that is easily maintainable and scalable.&lt;br /&gt;
&lt;br /&gt;
[[File:Example.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149625</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149625"/>
		<updated>2023-04-13T00:38:23Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
https://vahid.blog/post/2021-04-16-understanding-the-model-view-controller-mvc-pattern/&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149620</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149620"/>
		<updated>2023-04-13T00:25:33Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149617</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149617"/>
		<updated>2023-04-13T00:24:22Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
* Sample test cases for '''BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149615</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149615"/>
		<updated>2023-04-13T00:24:06Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
*'''Sample test cases for BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149613</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149613"/>
		<updated>2023-04-13T00:23:50Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
'''Testing with Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''Testing with RSpec'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
'''Sample test cases for BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149611</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149611"/>
		<updated>2023-04-13T00:22:57Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
'''API testing using Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
'''RSpec Test Cases'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
'''Sample test cases for BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149610</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149610"/>
		<updated>2023-04-13T00:22:47Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
'''API testing using Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''RSpec Test Cases'''&lt;br /&gt;
&lt;br /&gt;
We will also be using RSpec test cases for testing the code base. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
'''Sample test cases for BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149609</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149609"/>
		<updated>2023-04-13T00:22:14Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
'''API testing using Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''RSpec Test Cases''''&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
'''Sample test cases for BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149607</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149607"/>
		<updated>2023-04-13T00:21:49Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
'''API testing using Postman'''&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
'''Sample test cases for BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149597</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149597"/>
		<updated>2023-04-13T00:11:29Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
*'''Sample test cases for BadgesController:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149595</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149595"/>
		<updated>2023-04-13T00:10:44Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Design and Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149593</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149593"/>
		<updated>2023-04-13T00:09:10Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Contributors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149592</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149592"/>
		<updated>2023-04-13T00:08:26Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: &lt;br /&gt;
      fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', &lt;br /&gt;
       'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. &amp;lt;br&amp;gt;&lt;br /&gt;
The contributors: &amp;lt;br&amp;gt;&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149591</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149591"/>
		<updated>2023-04-13T00:07:20Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
context &amp;quot;with invalid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;does not create a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.not_to change(Badge, :count)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;renders the new template&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to render_template(:new)&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;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. &amp;lt;br&amp;gt;&lt;br /&gt;
The contributors: &amp;lt;br&amp;gt;&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149587</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149587"/>
		<updated>2023-04-13T00:05:06Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RSpec.describe BadgesController, type: :controller do&lt;br /&gt;
  describe &amp;quot;GET #index&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns a successful response&amp;quot; do&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(response).to be_successful&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it &amp;quot;assigns all badges to @badges&amp;quot; do&lt;br /&gt;
      badge = Badge.create(name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;)&lt;br /&gt;
      get :index&lt;br /&gt;
      expect(assigns(:badges)).to eq([badge])&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;
 describe &amp;quot;POST #create&amp;quot; do&lt;br /&gt;
    context &amp;quot;with valid attributes&amp;quot; do&lt;br /&gt;
      it &amp;quot;creates a new badge&amp;quot; do&lt;br /&gt;
        expect {&lt;br /&gt;
          post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        }.to change(Badge, :count).by(1)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      it &amp;quot;redirects to the badges index page&amp;quot; do&lt;br /&gt;
        post :create, params: { badge: { name: &amp;quot;Test Badge&amp;quot;, description: &amp;quot;This is a test badge&amp;quot;, image_file: fixture_file_upload(Rails.root.join('spec', 'fixtures', 'badge.png'), 'image/png') } }&lt;br /&gt;
        expect(response).to redirect_to(badges_url)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. &amp;lt;br&amp;gt;&lt;br /&gt;
The contributors: &amp;lt;br&amp;gt;&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149581</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149581"/>
		<updated>2023-04-12T23:58:32Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the BadgesController as well as the DutiesController, we have the scope to write the test cases and test the CRUD operations and their functionalities. We can test the API functionalities by writing test cases for testing the get, patch, and post API calls. The following is an example test case of how we can test and write the scripts for the controller. Given below is a example of an RSpec test case for BadgesController and its operations:&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. &amp;lt;br&amp;gt;&lt;br /&gt;
The contributors: &amp;lt;br&amp;gt;&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149451</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149451"/>
		<updated>2023-04-12T18:49:12Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Design Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design and Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. &amp;lt;br&amp;gt;&lt;br /&gt;
The contributors: &amp;lt;br&amp;gt;&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149442</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149442"/>
		<updated>2023-04-12T16:19:38Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Design Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:''' To reimplement the DutiesController in a more modular, reusable and efficient, we can do the following changes :-&lt;br /&gt;
# Check if the user is authorized to perform the actions on the resource.&lt;br /&gt;
# Removed the action_allowed? method.&lt;br /&gt;
# As the record is already found, we can remove 'find' from 'update_attributes'.&lt;br /&gt;
# Changed the delete action to destroy for consistency with Rails conventions.&lt;br /&gt;
# Add a rescue block in set_duty to handle cases when the duty record is not found.&lt;br /&gt;
# Display errors in a more user friendly format.&lt;br /&gt;
# Remove 'AuthorizationHelper' since we are using 'authorize_resource'.&lt;br /&gt;
# Change the parameter fetching of assignment_id to '@duty.assignment_id' as this increases dependency on user input a lot.&lt;br /&gt;
# Removing unnecessary semicolons.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the 'duties_controller.rb'&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# frozen_string_literal: true&lt;br /&gt;
&lt;br /&gt;
class DutiesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  # duties can be created/modified by Teaching Assistants, Instructor, Admin, Super Admin&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  before_action :set_duty, only: %i[show edit update destroy]&lt;br /&gt;
&lt;br /&gt;
  # GET /duties&lt;br /&gt;
  def index&lt;br /&gt;
    @duties = Duty.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1&lt;br /&gt;
  def show; end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/new&lt;br /&gt;
  def new&lt;br /&gt;
    @duty = Duty.new&lt;br /&gt;
    @id = params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /duties/1/edit&lt;br /&gt;
  def edit; end&lt;br /&gt;
&lt;br /&gt;
  # POST /duties&lt;br /&gt;
  def create&lt;br /&gt;
    @duty = Duty.new(duty_params)&lt;br /&gt;
&lt;br /&gt;
    if @duty.save&lt;br /&gt;
      # When the duty (role) is created successfully we return back to the assignment edit page&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully created.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /duties/1&lt;br /&gt;
  def update&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
&lt;br /&gt;
    if @duty.update_attributes(duty_params)&lt;br /&gt;
      redirect_to edit_assignment_path(params[:duty][:assignment_id]), notice: 'Role was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to_create_page_and_show_error&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
    @duty.destroy&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]),&lt;br /&gt;
                notice: 'Role was successfully deleted.'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Use callbacks to share common setup or constraints between actions.&lt;br /&gt;
  def set_duty&lt;br /&gt;
    @duty = Duty.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_create_page_and_show_error&lt;br /&gt;
    error_messages = []&lt;br /&gt;
    @duty.errors.each { |_, error| error_messages.append(error) }&lt;br /&gt;
    error_message = error_messages.join('. ')&lt;br /&gt;
    flash[:error] = error_message&lt;br /&gt;
    redirect_to action: :new, id: params[:duty][:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def duty_params&lt;br /&gt;
    params.require(:duty).permit(:assignment_id, :max_members_for_duty, :name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the existing code for 'duty.rb':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Duty &amp;lt; ApplicationRecord&lt;br /&gt;
  belongs_to :assignment&lt;br /&gt;
  # validates name with format matching regex, length to be at least 3 and&lt;br /&gt;
  # same name cannot be assigned to multiple duties in particular assignment.&lt;br /&gt;
  validates :name,&lt;br /&gt;
            format: { with: /\A[^`!@#\$%\^&amp;amp;*+_=]+\z/,&lt;br /&gt;
                      message: 'Please enter a valid role name' },&lt;br /&gt;
            length: {&lt;br /&gt;
              minimum: 3,&lt;br /&gt;
              message: 'Role name is too short (minimum is 3 characters)'&lt;br /&gt;
            },&lt;br /&gt;
            uniqueness: {&lt;br /&gt;
              case_sensitive: false, scope: :assignment,&lt;br /&gt;
              message: 'The role &amp;quot;%{value}&amp;quot; is already present for this assignment'&lt;br /&gt;
            }&lt;br /&gt;
  validates_numericality_of :max_members_for_duty,&lt;br /&gt;
                            only_integer: true,&lt;br /&gt;
                            greater_than_or_equal_to: 1,&lt;br /&gt;
                            message: 'Value for max members for role is invalid'&lt;br /&gt;
&lt;br /&gt;
  # E2147 : check if the duty selected is available for selection in that particular team. Checks whether&lt;br /&gt;
  # current duty count in the team is less than the max_members_for_duty set for that particular duty&lt;br /&gt;
  def can_be_assigned?(team)&lt;br /&gt;
    max_members_for_duty &amp;gt; team.participants.select { |team_member| team_member.duty_id == id }.count&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. &lt;br /&gt;
&lt;br /&gt;
In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. &amp;lt;br&amp;gt;&lt;br /&gt;
The contributors: &amp;lt;br&amp;gt;&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149236</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149236"/>
		<updated>2023-04-08T01:13:32Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Add re-implementation logic and details here&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
For testing the DutiesController and BadgesController, as well as the Duty and Badge model classes, we plan to employ Postman to test each route of the DutiesController and BadgesController. We plan to test if the expected response is obtained by making valid requests using the correct parameters for each endpoint. In addition, we will check if each method behaves as anticipated by making requests with an incorrect number of parameters, invalid parameter types, and values, and checked if the endpoint throws a status 422 Invalid Request as the response. Testing via Postman will help ensure that each API endpoint handled both valid and invalid requests and behave as intended.&lt;br /&gt;
&lt;br /&gt;
Moreover, we will be using RSpec test cases. This will allow us to write tests that are independent of any external dependencies and can be easily run to validate the functionality of our code. With RSpec, we can write unit tests that focus on individual pieces of functionality and integration tests that test the interactions between different components. By using RSpec, we can have greater confidence in the correctness of our code and quickly identify any issues that may arise as changes are made. We look forward to utilizing RSpec to ensure that our DutiesController, BadgesController, Duty, and Badge model classes are thoroughly tested and free of errors.&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. &amp;lt;br&amp;gt;&lt;br /&gt;
The contributors: &amp;lt;br&amp;gt;&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149233</id>
		<title>E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149233"/>
		<updated>2023-04-08T01:07:53Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: Sstangad moved page E2347. Reimplement duties controller.rb and badges controller.rb to CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb: Include more details in title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb]]&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149232</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149232"/>
		<updated>2023-04-08T01:07:53Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: Sstangad moved page E2347. Reimplement duties controller.rb and badges controller.rb to CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb: Include more details in title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Add re-implementation logic and details here&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. &amp;lt;br&amp;gt;&lt;br /&gt;
The contributors: &amp;lt;br&amp;gt;&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149222</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149222"/>
		<updated>2023-04-08T00:55:22Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Contributors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Add re-implementation logic and details here&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. &amp;lt;br&amp;gt;&lt;br /&gt;
The contributors: &amp;lt;br&amp;gt;&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
Mentor: &amp;lt;br&amp;gt;&lt;br /&gt;
Kartiki Bhandakkar(kbhanda3@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149220</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149220"/>
		<updated>2023-04-08T00:53:56Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Contributors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Add re-implementation logic and details here&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. &amp;lt;br&amp;gt;&lt;br /&gt;
The contributors: &amp;lt;br&amp;gt;&lt;br /&gt;
Sanket Tangade(sstangad@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Kunal Patil(kpatil5@ncsu.edu) &amp;lt;br&amp;gt;&lt;br /&gt;
Yash Sonar(ysonar@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149215</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149215"/>
		<updated>2023-04-08T00:51:10Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Add re-implementation logic and details here&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were:&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149212</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149212"/>
		<updated>2023-04-08T00:49:30Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
We have given two controllers, duties_controller.rb and badges_controller.rb where we have to reimplement the code using a more object-oriented and efficient way. One potential way to refactor this code in a more object-oriented and efficient manner is to extract responsibilities into smaller objects with clear roles and interfaces. This can help reduce complexity and coupling between different parts of the system, making it easier to maintain and extend over time. Additionally, adopting design patterns and principles like SOLID can help improve the overall quality and modularity of the codebase. Overall, investing time and effort in improving the design and architecture of the code can pay off in the long term by reducing technical debt and enabling faster and more effective development.&lt;br /&gt;
&lt;br /&gt;
After gaining a grasp of the system's flow, we delved into the code within the controllers. Upon initial inspection, it became apparent that the controllers were managing all of the CRUD operations but there were some minor changes that can enhance it and make it more readable and easy to understand. We discerned which functionalities did not pertain to the duties_controler as well as the badges_controller and determined which redundant code should be eliminated. Our reimplementation project has addressed the following issues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''duties_controller.rb:'''&lt;br /&gt;
&lt;br /&gt;
*'''badges_controller.rb:''' To reimplement the BadgesController in a more object-oriented and efficient way, you could split it into a Badge model and a BadgesController controller, following the Model-View-Controller (MVC) pattern. Earlier, all the CRUD methods as well as the dependent methods were written in the same controller class which is not much of the preferred way to write code logic in an MVC pattern and follow the principles. We planned to move the dependent and validation method to the Badge.rb model class where it would be more easier and coder-friendly to understand and work with the code in the future as well.&lt;br /&gt;
&lt;br /&gt;
Here is the previous code of the &amp;quot;badges_controller.rb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_assignment&lt;br /&gt;
    redirect_to session.delete(:return_to)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    image_file = params[:badge][:image_file]&lt;br /&gt;
    if image_file&lt;br /&gt;
      File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_file.original_filename), 'wb') do |file|&lt;br /&gt;
        file.write(image_file.read)&lt;br /&gt;
      end&lt;br /&gt;
      @badge.image_name = image_file.original_filename&lt;br /&gt;
    else&lt;br /&gt;
      @badge.image_name = ''&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to session.delete(:return_to), notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is how we planned to implement the &amp;quot;Badge.rb&amp;quot; model class: &lt;br /&gt;
&lt;br /&gt;
This model will handle the validations and image upload for the Badge object. The upload_image method can be called from the create action in the BadgesController to save the image to the file system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Badge &amp;lt; ApplicationRecord&lt;br /&gt;
&lt;br /&gt;
  def self.upload_image(image_file)&lt;br /&gt;
    return '' unless image_file&lt;br /&gt;
&lt;br /&gt;
    image_name = image_file.original_filename&lt;br /&gt;
    File.open(Rails.root.join('app', 'assets', 'images', 'badges', image_name), 'wb') do |file|&lt;br /&gt;
      file.write(image_file.read)&lt;br /&gt;
    end&lt;br /&gt;
    image_name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, we planned to re-implement the BadgesController.rb as follows:&lt;br /&gt;
&lt;br /&gt;
This BadgesController now follows the RESTful conventions, which makes it easier to understand and maintain. It also leverages the Badge model to handle the validations and image upload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class BadgesController &amp;lt; ApplicationController&lt;br /&gt;
  include AuthorizationHelper&lt;br /&gt;
&lt;br /&gt;
  before_action :set_return_to, only: [:new]&lt;br /&gt;
  before_action :set_badge, only: [:show, :edit, :update, :destroy]&lt;br /&gt;
&lt;br /&gt;
  def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges&lt;br /&gt;
  def index&lt;br /&gt;
    @badges = Badge.all&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # GET /badges/new&lt;br /&gt;
  def new&lt;br /&gt;
    @badge = Badge.new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # POST /badges&lt;br /&gt;
  def create&lt;br /&gt;
    @badge = Badge.new(badge_params)&lt;br /&gt;
    @badge.image_name = Badge.upload_image(params[:badge][:image_file])&lt;br /&gt;
&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      if @badge.save&lt;br /&gt;
        format.html { redirect_to redirect_to_url, notice: 'Badge was successfully created' }&lt;br /&gt;
      else&lt;br /&gt;
        format.html { render :new }&lt;br /&gt;
        format.json { render json: @badge.errors, status: :unprocessable_entity }&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PATCH/PUT /badges/1&lt;br /&gt;
  def update&lt;br /&gt;
    if @badge.update(badge_params)&lt;br /&gt;
      redirect_to @badge, notice: 'Badge was successfully updated.'&lt;br /&gt;
    else&lt;br /&gt;
      render :edit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  def set_badge&lt;br /&gt;
    @badge = Badge.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_return_to&lt;br /&gt;
    session[:return_to] ||= request.referer&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_to_url&lt;br /&gt;
    session.delete(:return_to) || badges_url&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def badge_params&lt;br /&gt;
    params.require(:badge).permit(:name, :description, :image_name)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were:&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149151</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149151"/>
		<updated>2023-04-07T22:13:09Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: /* Goals of this Project */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Aim of this Project==&lt;br /&gt;
The aim of this Project is:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were:&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149149</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149149"/>
		<updated>2023-04-07T22:06:16Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Goals of this Project==&lt;br /&gt;
The goals of this Project are:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were:&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149147</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149147"/>
		<updated>2023-04-07T22:04:13Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: Goals of this Project&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Goals of this Project==&lt;br /&gt;
The goals of this Project are:&lt;br /&gt;
&lt;br /&gt;
#Re-implementing CRUD operations for each controller&lt;br /&gt;
#Fix bugs and minor flows in the existing code base and functionality&lt;br /&gt;
#Removing redundant or unclear code logic&lt;br /&gt;
#Writing RSpec test scripts for both the controllers&lt;br /&gt;
&lt;br /&gt;
By meeting these objectives, both controllers can perform their fundamental create, read, update, and delete operations, while also improving the code's readability and functionality. Additionally, it will aid in addressing any current bugs, thereby enhancing the accuracy of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were:&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149140</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149140"/>
		<updated>2023-04-07T21:40:28Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: Added Problem Statement&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
The problem at hand involves the Duties and Badge modules of Expertiza. Mainly, the task is to improve the code logic and design by following the Object Oriented Design principles and methods and make the code base more efficient, easy to read and structured. We have two controller classes &amp;quot;duties_controller.rb&amp;quot; and &amp;quot;badge_controller.rb&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The duties_controller in the Duties module defines several actions, including create, edit, update, and delete. The create action is used to save the new duty to the database, while the edit action renders the form for editing an existing duty. The update action updates the duty in the database, and the delete action deletes a duty from the database.&lt;br /&gt;
&lt;br /&gt;
On the other hand, the Badge module has a create action that creates a new Badge instance using user parameters and saves an image file if attached. It also updates the image_name attribute of the badge instance. Additionally, there is a new action that sets up a new Badge instance and a redirect_to_assignment method to redirect to the previous page visited by the user. This method is used with the new action to keep track of the page the user was on when they requested a new Badge instance.&lt;br /&gt;
&lt;br /&gt;
The task is to ensure that the Duties and Badge modules function correctly and that the create, edit, update, delete, and new actions all work as intended as well as to optimize, restructure and reimplement the code by following the Object Oriented way. This will help manage duties and badges in Expertiza effectively.&lt;br /&gt;
&lt;br /&gt;
==Goals of this Project==&lt;br /&gt;
The goals of this Project are:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
By achieving these goals, both the controllers can have their basic CRUD functionalities as well as it will also ensure that the code readability and functionality of the code for the two controllers is increased. It will also help in resolving the existing bugs which will increase correctness of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were:&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149132</id>
		<title>CSC/ECE 517 Spring 2023 -E2347. Reimplement duties controller.rb and badges controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2347._Reimplement_duties_controller.rb_and_badges_controller.rb&amp;diff=149132"/>
		<updated>2023-04-07T21:25:53Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: Create E2347. Reimplement duties_controller.rb and badges_controller.rb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Goals of this Project==&lt;br /&gt;
The goals of this Project are:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
By achieving these goals, both the controllers can have their basic CRUD functionalities as well as it will also ensure that the code readability and functionality of the code for the two controllers is increased. It will also help in resolving the existing bugs which will increase correctness of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were:&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2319._Reimplement_questionnaire.rb&amp;diff=148300</id>
		<title>CSC/ECE 517 Spring 2023 - E2319. Reimplement questionnaire.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2319._Reimplement_questionnaire.rb&amp;diff=148300"/>
		<updated>2023-03-23T03:50:57Z</updated>

		<summary type="html">&lt;p&gt;Sstangad: Added get_weighted_score&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Problem Description ==&lt;br /&gt;
&lt;br /&gt;
The model for questionnaire needs to be reimplemented to account for new features of recent versions of Ruby and Rails. The reimplementation of this model should consider SOLID principles and implement design patterns where relevant. The reimplementation should also consider object-oriented fundamentals like readability, eliminating redundancy, polymorphism, etc. The features available in the Ruby/Rails framework can be leveraged to accomplish these goals.&lt;br /&gt;
&lt;br /&gt;
== Methods Reimplemented ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Model Validations &amp;amp; the “validate_questionnaire” method'''&lt;br /&gt;
&lt;br /&gt;
[[File:Validations reimplementation.png|1300px]]&lt;br /&gt;
&lt;br /&gt;
In reimplementing the validation functionality of the questionnaire model, the “validate_questionnaire” method was removed entirely as it added unnecessary complexity to display errors based on if statement conditions. To replace the functionality of the “validate_questionnaire” method, active record validations using helpers were added instead. Using Active Record validations allow for better leverage of Rails’ built-in framework rather than duplicating the work the Rails is already capable of by writing conditions and queries to determine when errors should display. This also keeps the implementation simpler and easier to manage when updates in the future are needed.&lt;br /&gt;
&lt;br /&gt;
There were four instances for when errors should arise to the end user from the “validate_questionnaire” method: (1) when the maximum question score entered was less than 1, (2) when the minimum question score entered was less than 0, (3) when the minimum question score entered was greater than the maximum question score, and (4) when a questionnaire is created with the name of an existing questionnaire created by the same instructor.&lt;br /&gt;
&lt;br /&gt;
The first three error instances were reimplemented using the Active Record validation helper “comparison.” The first error instance, when the maximum question score entered was less than 1, was accomplished by adding a comparison to ensure that the maximum question score is greater than 0, otherwise the message “The maximum question score must be a positive integer greater than 0” will display, which is a more descriptive message than the original. The second error instance was implemented similarly to the first except for the validation was created for the minimum question score and ensured that the value is greater than or equal to 0. The third error instance was reimplemented by adding a comparison between the minimum question score and the maximum question score toe ensure that the maximum is always greater than the minimum.&lt;br /&gt;
&lt;br /&gt;
Lastly, the fourth error instance of the “validate_questionnaire” method, when a questionnaire is created with the name of an existing questionnaire created by the same instructor, was reimplemented by adding the Active Record validation helper “uniqueness” to the existing name validation. In addition, the &amp;quot;uniqueness&amp;quot; helper had a scope added to ensure that uniqueness is only applied for the combination of name and instructor_id. The added uniqueness scope allows for the name to be the same on two questionnaires if created by two different instructors.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''“get_weighted_score” and “compute_weighted_score” methods'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
These methods are used to fetch and calculate the weighted scores of all the questionnaires. &lt;br /&gt;
While reimplementing these methods, in the &amp;quot;get_weighted_score&amp;quot; method, instead of explicitly writing the nil check condition for the &amp;quot;used_in_round&amp;quot; attribute, the safe navigation operator &amp;quot;&amp;amp;&amp;quot; is used. This ensures that the code doesn't break if the object is nil as well as it gets rid of the check condition for the &amp;quot;nil&amp;quot; value as it is automatically handled by the &amp;quot;&amp;amp;&amp;quot; operator. Also, the &amp;quot;if-else&amp;quot; condition is replaced with the ternary operator for brevity and readability. The questionnaire_symbol is now being built using the string concatenation instead of calling &amp;quot;to_s&amp;quot; on the symbol and then concatenating the result with round.to_s. This is a more concise and readable way of building the symbol.&lt;br /&gt;
&lt;br /&gt;
For the &amp;quot;compute_weighted_score&amp;quot; method, while reimplementing, instead of using the array indexing way to fetch data from the variables, the &amp;quot;dig&amp;quot; method is used to retrieve the :avg score from the scores hash. The &amp;quot;dig&amp;quot; method will return nil if any of the intermediate keys are nil, so it's safe to use here as the nil condition check is done by the dig method itself instead of explicitly writing it. The use of the ternary operator is again implemented in this method as well for brevity and readability. Overall, these changes should make the code more concise, efficient, and easier to read.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''“true_false_questions?” method'''&lt;br /&gt;
&lt;br /&gt;
[[File:Has_true_false_questions_reimplementation.png|1200px]]&lt;br /&gt;
&lt;br /&gt;
When reimplementing this method, the name of the method was changed to “has_true_false_questions” to be more descriptive of what a true vs false return of this method means. &lt;br /&gt;
&lt;br /&gt;
This method is checking to see if there are any true/false questions associated with a questionnaire. If there are, it returns true. If there are not, the method returns false.&lt;br /&gt;
&lt;br /&gt;
The original implementation of this method used the “each” method of the Array object to loop through the associated question records and return true once it came across upon a question with the type “Checkbox.” In the updated implementation of this class, instead of using “each,” the “any?” method of the Array object is used. The “any?” method automatically returns true if the criterion is met and does not need it explicitly stated within the loop like in the original implementation, allowing for the removal of unnecessary syntax.&lt;br /&gt;
&lt;br /&gt;
The logic this method is intended for is more suited for the “any?” method than the “each” method. This is because the original implementation using “each” was re-writing what “any?” already does. Using “any?” also allows for better readability as it is much clearer after the reimplementation that the method will return true if any question record meets the criteria (type equals ‘Checkbox’).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''“delete” method'''&lt;br /&gt;
&lt;br /&gt;
When evaluating the &amp;quot;delete&amp;quot; method for reimplementation, it was realized that this functionality is already being done by the questionnaires controller [https://github.com/expertiza/expertiza/blob/main/app/controllers/questionnaires_controller.rb#L143]. For this reason, this method was removed in the reimplementation of this model to follow the DRY principle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''“max_possible_score” method'''&lt;br /&gt;
&lt;br /&gt;
[[File:Max_possible_score_reimplementation.png|1200px]]&lt;br /&gt;
&lt;br /&gt;
The “max_possible_method” method adds the values of the “weight” attribute of each question record related to the questionnaire and then multiplies that sum by the “max_question_score” of the questionnaire.&lt;br /&gt;
&lt;br /&gt;
The original implementation of this method included a complex and difficult to read query which was completing all of the calculations within it.&lt;br /&gt;
&lt;br /&gt;
To make this more readable and easier to update in the future several updates were made. Firstly, the reimplementation separated the summation and the multiplication operations, so that it is easier to follow how the final value is calculated and allows ease of modifications in the future. Additionally, rather than using a complex query to sum the related questions’ weight values, the “sum” method of the Array object is used instead to take advantage of Ruby’s duck typing capability and the Enumerable mixin. Using the “sum” method significantly improves readability.&lt;br /&gt;
&lt;br /&gt;
The reimplementation also takes advantage of the Distributive Property in math by ensuring that the sum is calculated before applying any multiplication, rather than multiplying each weight and then summing the multiplied values. The reimplementation ensures that the calculation ‘cost effective’ in terms of CPU cycles.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''“self.copy_questionnaire_details” method'''&lt;br /&gt;
&lt;br /&gt;
[[File:Copy questionnaire details.png|900px]]&lt;br /&gt;
[[File:Copy questionnaire details 2.png|900px]]&lt;br /&gt;
&lt;br /&gt;
The “self.copy_questionnaire_details” method creates a cloned copy of the provided questionnaire for a given instructor, including the associated models such as Questions, and Question Advices for each Question.&lt;br /&gt;
&lt;br /&gt;
The original implementation is very cluttered and difficult to read and interpret, as it creates new cloned objects for Questions and QuestionAdvice within the main method itself.&lt;br /&gt;
&lt;br /&gt;
To improve this in the re-implementation, we have firstly used more descriptive and consistent nomenclature for the original and cloned objects for Questionnaire, Question and QuestionAdvice. Next, we have separated the methods for creation of clones for Questionnaire, Question and QuestionAdvice, thus making it more readable. We have also clearly marked the steps involved in the reimplementation to make it easier for the reader to understand the order of cloning operations involved within the method.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
The goal is to test every possible scenario. Since this is the reimplementation of a model, there are only system tests. The tests will leverage the RSpec framework and FactoryBot to stub associated records.&lt;br /&gt;
&lt;br /&gt;
In order to properly stub, skeleton models of associations will be created (assignment, assignment_questionnaire, instructor, question, and questionnaire_node). Also, in order to stub successfully, tables for the associations will be created before all tests, and dropped after all tests.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Model Validations &amp;amp; the “validate_questionnaire” method'''&lt;br /&gt;
&lt;br /&gt;
Tests are to be written to ensure proper validations were in place. Some of these will use the “shoulda matchers” gem to ensure implementation of the validations as the reimplementation will be done in TDD. Additionally, behavior should be tested by ensuring the validation errors arise when expected and by ensuring valid inputs are accepted.&lt;br /&gt;
&lt;br /&gt;
For the name attribute, validation tests for behavior should ensure that a questionnaire without a name ''cannot'' be saved, a questionnaire with the same name as another questionnaire ''cannot'' be saved if the instructor is the same on both questionnaires, and a questionnaire with the same name as another questionnaire ''can'' be saved if the instructors are different on each questionnaire.&lt;br /&gt;
&lt;br /&gt;
For testing the validations on the min_question_score and max_question_score attributes, tests should ensure that a non-numeric value entered in either the min_question_score or max_question_score fields ''cannot'' be saved, that the min_question_score ''cannot'' be saved unless it is 0 or greater, that the max_question_score ''cannot'' be saved unless it is 1 or greater, and that the questionnaire ''cannot'' be saved if the min_question_score is greater than the max_question_score. A test should also be written to confirm that the questionnaire ''can'' save successfully when valid inputs are entered for these attributes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''“get_weighted_score” and “compute_weighted_score” methods'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''“true_false_questions?” method'''&lt;br /&gt;
&lt;br /&gt;
Three outcomes should tested for this method:&lt;br /&gt;
&lt;br /&gt;
(1) confirming the method returns true if there is a true/false question related to the questionnaire,&lt;br /&gt;
&lt;br /&gt;
(2) confirming the method returns false if there are questions related to the questionnaire but none are true/false, and&lt;br /&gt;
&lt;br /&gt;
(3) confirming the method returns false if there are no questions related to the questionnaire at all.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''“delete” method'''&lt;br /&gt;
&lt;br /&gt;
Two outcomes should be tested for this method:&lt;br /&gt;
&lt;br /&gt;
(1) Ensure that when a questionnaire without assignments enters this method, the questionnaire itself is destroyed along with its associated question records and questionnaire node record.&lt;br /&gt;
&lt;br /&gt;
(2) Ensure that when a questionnaire with a related assignment enters this method, a Runtime Error is raised.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''“max_possible_score” method'''&lt;br /&gt;
&lt;br /&gt;
Three scenarios should be tested for this method to ensure calculation is correct:&lt;br /&gt;
&lt;br /&gt;
(1) Ensure that the max_possible_score returned is what is expected when there are two related questions of different weights.&lt;br /&gt;
&lt;br /&gt;
(2) Ensure that the max_possible_score changes to a different expected value when a third question is added to the questionnaire.&lt;br /&gt;
&lt;br /&gt;
(3) Ensure that the max_possible_score changes to a different expected value when the same three questions from the second scenario are associated but the max_question_score value is changed on the questionnaire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''“self.copy_questionnaire_details” method'''&lt;br /&gt;
Test is written to ensure the expected behavior for fetching the related questions provided the questionnaire to be cloned and for fetching advices for each question.&lt;br /&gt;
&lt;br /&gt;
== Test Coverage ==&lt;br /&gt;
&lt;br /&gt;
After implementing tests, test coverage is nearly 100%:&lt;br /&gt;
&lt;br /&gt;
[[File:Test_coverage_dbaidya.png|1000px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Below are test coverage details from SimpleCov:&lt;br /&gt;
&lt;br /&gt;
[[File:Test_coverage_details.png|1200px]]&lt;/div&gt;</summary>
		<author><name>Sstangad</name></author>
	</entry>
</feed>