Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions app/controllers/doctor_question_types_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
class DoctorQuestionTypesController < ApplicationController
before_action :set_doctor_question_type, only: %i[ show edit update destroy ]

# GET /doctor_question_types or /doctor_question_types.json
def index
@doctor_question_types = DoctorQuestionType.includes(:doctor_questions).all
end

# GET /doctor_question_types/1 or /doctor_question_types/1.json
def show
end

# GET /doctor_question_types/new
def new
@doctor_question_type = DoctorQuestionType.new
end

# GET /doctor_question_types/1/edit
def edit
end

# POST /doctor_question_types or /doctor_question_types.json
def create
@doctor_question_type = DoctorQuestionType.new(doctor_question_type_params)

respond_to do |format|
if @doctor_question_type.save
format.html { redirect_to @doctor_question_type, notice: "Doctor question type was successfully created." }
format.json { render :show, status: :created, location: @doctor_question_type }
else
format.html { render :new, status: :unprocessable_content }
format.json { render json: @doctor_question_type.errors, status: :unprocessable_content }
end
end
end

# PATCH/PUT /doctor_question_types/1 or /doctor_question_types/1.json
def update
respond_to do |format|
if @doctor_question_type.update(doctor_question_type_params)
format.html { redirect_to @doctor_question_type, notice: "Doctor question type was successfully updated.", status: :see_other }
format.json { render :show, status: :ok, location: @doctor_question_type }
else
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @doctor_question_type.errors, status: :unprocessable_content }
end
end
end

# DELETE /doctor_question_types/1 or /doctor_question_types/1.json
def destroy
@doctor_question_type.destroy!

respond_to do |format|
format.html { redirect_to doctor_question_types_path, notice: "Doctor question type was successfully destroyed.", status: :see_other }
format.json { head :no_content }
end
end

private
# Use callbacks to share common setup or constraints between actions.
def set_doctor_question_type
@doctor_question_type = DoctorQuestionType.find(params.expect(:id))
end

# Only allow a list of trusted parameters through.
def doctor_question_type_params
params.expect(doctor_question_type: [ :name ])
end
end
70 changes: 70 additions & 0 deletions app/controllers/doctor_questions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
class DoctorQuestionsController < ApplicationController
before_action :set_doctor_question, only: %i[ show edit update destroy ]

# GET /doctor_questions or /doctor_questions.json
def index
@doctor_questions = DoctorQuestion.sorted_by(params[:sort], params[:direction])
end

# GET /doctor_questions/1 or /doctor_questions/1.json
def show
end

# GET /doctor_questions/new
def new
@doctor_question = DoctorQuestion.new
end

# GET /doctor_questions/1/edit
def edit
end

# POST /doctor_questions or /doctor_questions.json
def create
@doctor_question = DoctorQuestion.new(doctor_question_params)

respond_to do |format|
if @doctor_question.save
format.html { redirect_to @doctor_question, notice: "Doctor question was successfully created." }
format.json { render :show, status: :created, location: @doctor_question }
else
format.html { render :new, status: :unprocessable_content }
format.json { render json: @doctor_question.errors, status: :unprocessable_content }
end
end
end

# PATCH/PUT /doctor_questions/1 or /doctor_questions/1.json
def update
respond_to do |format|
if @doctor_question.update(doctor_question_params)
format.html { redirect_to @doctor_question, notice: "Doctor question was successfully updated.", status: :see_other }
format.json { render :show, status: :ok, location: @doctor_question }
else
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @doctor_question.errors, status: :unprocessable_content }
end
end
end

# DELETE /doctor_questions/1 or /doctor_questions/1.json
def destroy
@doctor_question.destroy!

respond_to do |format|
format.html { redirect_to doctor_questions_path, notice: "Doctor question was successfully destroyed.", status: :see_other }
format.json { head :no_content }
end
end

private
# Use callbacks to share common setup or constraints between actions.
def set_doctor_question
@doctor_question = DoctorQuestion.find(params.expect(:id))
end

# Only allow a list of trusted parameters through.
def doctor_question_params
params.expect(doctor_question: [ :question, :doctor_question_type_id ])
end
end
14 changes: 14 additions & 0 deletions app/helpers/doctor_questions_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module DoctorQuestionsHelper
# A column heading that links back to the index with the sort it should apply.
# Clicking the column already sorted flips the direction; clicking any other
# starts it ascending.
def doctor_question_sort_link(column, label)
sorting_by_this = params[:sort].to_s == column
descending = params[:direction].to_s == "desc"

direction = sorting_by_this && !descending ? "desc" : "asc"
arrow = sorting_by_this ? (descending ? " ▼" : " ▲") : ""

link_to "#{label}#{arrow}", doctor_questions_path(sort: column, direction: direction)
end
end
27 changes: 27 additions & 0 deletions app/models/doctor_question.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class DoctorQuestion < ApplicationRecord
belongs_to :doctor_question_type

validates :question, presence: true, length: { maximum: 1000 }

# A whitelist, not a lookup table: params never reach the Arel.sql below.
SORT_COLUMNS = {
"type" => "doctor_question_types.name",
"question" => "doctor_questions.question"
}.freeze

DEFAULT_SORT = "type"

scope :sorted_by, ->(column, direction) {
column = SORT_COLUMNS.fetch(column) { SORT_COLUMNS.fetch(DEFAULT_SORT) }
direction = direction == "desc" ? "desc" : "asc"

# references forces the LEFT JOIN that ordering on the types table needs;
# includes on its own would load them in a second query with nothing to sort
# on. created_at settles rows the chosen column ties on, so questions stay
# in the order they were added within a type rather than an arbitrary one.
includes(:doctor_question_type)
.references(:doctor_question_types)
.order(Arel.sql("#{column} #{direction}"))
.order(:created_at)
}
end
5 changes: 5 additions & 0 deletions app/models/doctor_question_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class DoctorQuestionType < ApplicationRecord
has_many :doctor_questions, dependent: :restrict_with_error

validates :name, presence: true, uniqueness: { case_sensitive: false }
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h2 id="<%= dom_id doctor_question_type %>" >
<%= link_to doctor_question_type.name, doctor_question_type %>
</h2>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json.extract! doctor_question_type, :id, :name, :created_at, :updated_at
json.url doctor_question_type_url(doctor_question_type, format: :json)
22 changes: 22 additions & 0 deletions app/views/doctor_question_types/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<%= form_with(model: doctor_question_type) do |form| %>
<% if doctor_question_type.errors.any? %>
<div style="color: red">
<h2><%= pluralize(doctor_question_type.errors.count, "error") %> prohibited this doctor_question_type from being saved:</h2>

<ul>
<% doctor_question_type.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>

<div>
<%= form.label :name, style: "display: block" %>
<%= form.text_field :name %>
</div>

<div>
<%= form.submit %>
</div>
<% end %>
12 changes: 12 additions & 0 deletions app/views/doctor_question_types/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<% content_for :title, "Editing doctor question type" %>

<h1>Editing doctor question type</h1>

<%= render "form", doctor_question_type: @doctor_question_type %>

<br>

<div>
<%= link_to "Show this doctor question type", @doctor_question_type %> |
<%= link_to "Back to doctor question types", doctor_question_types_path %>
</div>
14 changes: 14 additions & 0 deletions app/views/doctor_question_types/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<p style="color: green"><%= notice %></p>

<% content_for :title, "Doctor question types" %>

<h1>Doctor question types</h1>

<div id="doctor_question_types">
<% @doctor_question_types.each do |doctor_question_type| %>
<%= render doctor_question_type %>
<ul>
<%= render doctor_question_type.doctor_questions%>
</ul>
<% end %>
</div>
1 change: 1 addition & 0 deletions app/views/doctor_question_types/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.array! @doctor_question_types, partial: "doctor_question_types/doctor_question_type", as: :doctor_question_type
11 changes: 11 additions & 0 deletions app/views/doctor_question_types/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<% content_for :title, "New doctor question type" %>

<h1>New doctor question type</h1>

<%= render "form", doctor_question_type: @doctor_question_type %>

<br>

<div>
<%= link_to "Back to doctor question types", doctor_question_types_path %>
</div>
10 changes: 10 additions & 0 deletions app/views/doctor_question_types/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<p style="color: green"><%= notice %></p>

<%= render @doctor_question_type %>

<div>
<%= link_to "Edit this doctor question type", edit_doctor_question_type_path(@doctor_question_type) %> |
<%= link_to "Back to doctor question types", doctor_question_types_path %>

<%= button_to "Destroy this doctor question type", @doctor_question_type, method: :delete %>
</div>
1 change: 1 addition & 0 deletions app/views/doctor_question_types/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.partial! "doctor_question_types/doctor_question_type", doctor_question_type: @doctor_question_type
3 changes: 3 additions & 0 deletions app/views/doctor_questions/_doctor_question.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<li id="<%= dom_id doctor_question %>">
<%= link_to doctor_question.question, doctor_question %>
</li>
2 changes: 2 additions & 0 deletions app/views/doctor_questions/_doctor_question.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json.extract! doctor_question, :id, :question, :doctor_question_type_id, :created_at, :updated_at
json.url doctor_question_url(doctor_question, format: :json)
32 changes: 32 additions & 0 deletions app/views/doctor_questions/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<%= form_with(model: doctor_question) do |form| %>
<% if doctor_question.errors.any? %>
<div style="color: red">
<h2><%= pluralize(doctor_question.errors.count, "error") %> prohibited this doctor_question from being saved:</h2>

<ul>
<% doctor_question.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>

<div>
<%= form.label :question, style: "display: block" %>
<%= form.textarea :question %>
</div>

<div>
<%= form.label :doctor_question_type_id, "Type", style: "display: block" %>
<%= form.collection_select :doctor_question_type_id,
DoctorQuestionType.order(:name),
:id,
:name,
{ prompt: "Choose a type" } %>
</div>


<div>
<%= form.submit %>
</div>
<% end %>
12 changes: 12 additions & 0 deletions app/views/doctor_questions/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<% content_for :title, "Editing doctor question" %>

<h1>Editing doctor question</h1>

<%= render "form", doctor_question: @doctor_question %>

<br>

<div>
<%= link_to "Show this doctor question", @doctor_question %> |
<%= link_to "Back to doctor questions", doctor_questions_path %>
</div>
27 changes: 27 additions & 0 deletions app/views/doctor_questions/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<p style="color: green"><%= notice %></p>

<% content_for :title, "Questions to be asked" %>

<h1>Questions to be asked</h1>

<table>
<thead>
<tr>
<th><%= doctor_question_sort_link "type", "Type" %></th>
<th><%= doctor_question_sort_link "question", "Question" %></th>
<th></th>
</tr>
</thead>

<tbody>
<% @doctor_questions.each do |doctor_question| %>
<tr id="<%= dom_id doctor_question %>">
<td><%= doctor_question.doctor_question_type.name %></td>
<td><%= doctor_question.question %></td>
<td><%= link_to "Show this doctor question", doctor_question %></td>
</tr>
<% end %>
</tbody>
</table>

<%= link_to "New doctor question", new_doctor_question_path %>
1 change: 1 addition & 0 deletions app/views/doctor_questions/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.array! @doctor_questions, partial: "doctor_questions/doctor_question", as: :doctor_question
11 changes: 11 additions & 0 deletions app/views/doctor_questions/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<% content_for :title, "New doctor question" %>

<h1>New doctor question</h1>

<%= render "form", doctor_question: @doctor_question %>

<br>

<div>
<%= link_to "Back to doctor questions", doctor_questions_path %>
</div>
10 changes: 10 additions & 0 deletions app/views/doctor_questions/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<p style="color: green"><%= notice %></p>

<%= render @doctor_question %>

<div>
<%= link_to "Edit this doctor question", edit_doctor_question_path(@doctor_question) %> |
<%= link_to "Back to doctor questions", doctor_questions_path %>

<%= button_to "Destroy this doctor question", @doctor_question, method: :delete %>
</div>
1 change: 1 addition & 0 deletions app/views/doctor_questions/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.partial! "doctor_questions/doctor_question", doctor_question: @doctor_question
3 changes: 2 additions & 1 deletion app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
equal billing with People and Prescriptions. %>
<%= link_to "Admin", admin_path,
aria: { current: ("page" if admin_area?) } %>

<%= link_to "Questions", doctor_question_types_path,
aria: { current: aria_current_section(doctor_question_types_path) } %>
<%# Devise signs out via DELETE, so this needs Turbo to issue the
verb. button_to would work without it, but it would land in the
nav as a filled button - and, being a delete, painted in the
Expand Down
Loading
Loading