Being RESTful Is Not Always Best For The User
Tags: ruby, sinatra, rest
Published: 2021-02-15 01:16:31

The RESTful convention has been invaluable regarding creating a consistency in the internet allowing for improved communication. However, as with most things in life, there are exceptions. My project involved having a page on which people can enter their medical histories and subjective reports. It would not be convenient for the user to enter part of the information on one page and then to proceed to the next page. This is separate from notes which a person may or may not make use of and therefore is appropriate to put on a separate page. 

This is the page being discussed:

------------------------------------------------------------------
           Medical Information Notepad
           Medical Information For Peter
General History:
Medical Conditions:
Medications:
Allergies:
Current Treatments:
Surgeries:
Immunizations With Dates:
The Current Problem:
Location of the Problem:
Any Observed Changes:
What You Are Feeling:
What Is The Level Of Discomfort On A Scale Of 1 To 10:
How Long This Has Been Going On:
Press Here To Enter The Above Information:
Press Here To Logout Without Saving The Information:
 -----------------------------------------------------------------

The issue with this arrangement regarding the history and subjective areas is that they come from two separate tables. Therefore, the name on the route cannot be RESTful and simply use the name of the table since we have two tables represented on the page. 
The schema is as follows:
 -----------------------------------------------------------------
create_table "comments", force: :cascade do |t|
    t.text    "identifier"
    t.text    "note"
    t.text    "items_to_discuss"
    t.text    "questions"
    t.integer "patient_id"
  end

  create_table "histories", force: :cascade do |t|
    t.text    "diagnoses"
    t.text    "medications"
    t.text    "allergies"
    t.text    "current_treatments"
    t.text    "surgeries"
    t.text    "immunizations_with_dates"
    t.integer "patient_id"
  end

  create_table "patients", force: :cascade do |t|
    t.string "username"
    t.string "password_digest"
  end

  create_table "subjectives", force: :cascade do |t|
    t.text    "location"
    t.text    "observed_changes"
    t.text    "sensation_changes"
    t.string  "scale_1_to_10"
    t.text    "length_of_time"
    t.integer "patient_id"
  end

end
------------------------------------------------------------------
This is the code for the page being discussed. As you can see, the two tables have their respective information entered separately even though two tables are being updated:

------------------------------------------------------------------

<div class="p-3 mb-2 bg-light text-dark"> 
<h1 class='text-center'><span class="border border-3">Medical Information Notepad</span></h1>
<h1 class='text-center'><span class="border border-3">Medical Information For <%= @patient.username %></span></h1>
<form method="post" action="/patients/<%= @patient.id %>/info">
    <h3><u>General History:</u></h3>
    Medical Conditions: <input type="diagnoses" name="histories[diagnoses]"><br> 
    Medications: <input type="medications" name="histories[medications]" ><br>
    Allergies: <input type="allergies" name="histories[allergies]"><br>
    Current Treatments: <input type="current_treatments" name="histories[current_treatments]"><br>
    Surgeries: <input type="surgeries" name="histories[surgeries]"><br>
    Immunizations With Dates: <input type="immunizations_with_dates" name="histories[immunizations_with_dates]"><br>
     
    <h3><u>The Current Problem:</u></h3>
    Location of the Problem:<input type="location" name="subjectives[location]"><br>
    Any Observed Changes: <input type="observed_changes" name="subjectives[observed_changes]"><br>
    What You Are Feeling: <input type="sensation_changes" name="subjectives[sensation_changes]"><br>
    What Is The Level Of Discomfort On A Scale Of 1 To 10: <input type="scale_1_to_10" name="subjectives[scale_1_to_10]"><br>
    How Long This Has Been Going On:<input type="length_of_time" name="subjectives[length_of_time]"><br>
    <h3><u>Press Here To Enter The Above Information:</u> <input type="submit" value="Save Information"></h3>
</form>
   
      
<form method="GET" action="/logout">
        <input type="hidden" value="DELETE" name="_method">
        <h3><u>Press Here To Logout Without Saving The Information:</u> <input type="submit" value="Logout"></h3>
</form>
</div>
Finally, the following code allows for the saving of information for both sections from the same page:

 post '/patients/:id/info' do
        redirect_if_not_logged_in
        patient = Patient.find(session["patient_id"])
        history = History.new(:diagnoses => params[:histories][:diagnoses])
        history.medications = params[:histories][:medications]
        history.allergies = params[:histories][:allergies]
        history.current_treatments = params[:histories][:current_treatments]
        history.surgeries = params[:histories][:surgeries]
        history.immunizations_with_dates = params[:histories][:immunizations_with_dates]
        history.patient_id = patient.id
        history.save
        subjective = Subjective.create(:location => params[:subjectives][:location])
        subjective.observed_changes = params[:subjectives][:observed_changes]
        subjective.sensation_changes = params[:subjectives][:sensation_changes]
        subjective.scale_1_to_10 = params[:subjectives][:scale_1_to_10]
        subjective.length_of_time = params[:subjectives][:length_of_time]
        subjective.patient_id = patient.id
        subjective.save
   
        redirect 'patients/:id/info'
    end
------------------------------------------------------------------
 
As is evident from the above code, the route ends with /info which is not a RESTful term as /show would be. However, it does convey the meaning of what is presented on the page.

In conclusion, RESTful convention should indeed be used as frequently as possible. This presentation gives an example where being non-RESTful can be justified.