diff --git a/.rubocop.yml b/.rubocop.yml index 68349d6..267d958 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -12,3 +12,6 @@ AllCops: # # Use `[a, [b, c]]` not `[ a, [ b, c ] ]` # Layout/SpaceInsideArrayLiteralBrackets: # Enabled: false + +Bundler/OrderedGems: + Enabled: true diff --git a/Gemfile b/Gemfile index d59d620..4ceebcc 100644 --- a/Gemfile +++ b/Gemfile @@ -2,23 +2,25 @@ source "https://rubygems.org" # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" gem "rails", "~> 8.1.3" -# The modern asset pipeline for Rails [https://github.com/rails/propshaft] -gem "propshaft" -# Use sqlite3 as the database for Active Record -gem "sqlite3", ">= 2.9.6" -# Use the Puma web server [https://github.com/puma/puma] -gem "puma", ">= 5.0" + + +gem "devise", "~> 5.0" # Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] gem "importmap-rails" -# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] -gem "turbo-rails" -# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] -gem "stimulus-rails" # Build JSON APIs with ease [https://github.com/rails/jbuilder] gem "jbuilder" - +# The modern asset pipeline for Rails [https://github.com/rails/propshaft] +gem "propshaft" +# Use the Puma web server [https://github.com/puma/puma] +gem "puma", ">= 5.0" # Handle Cross-Origin Resource Sharing so the Expo app can call the API [https://github.com/cyu/rack-cors] gem "rack-cors" +# Use sqlite3 as the database for Active Record +gem "sqlite3", ">= 2.9.6" +# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] +gem "stimulus-rails" +# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] +gem "turbo-rails" # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] # gem "bcrypt", "~> 3.1.7" @@ -27,9 +29,9 @@ gem "rack-cors" gem "tzinfo-data", platforms: %i[ windows jruby ] # Use the database-backed adapters for Rails.cache, Active Job, and Action Cable +gem "solid_cable" gem "solid_cache" gem "solid_queue" -gem "solid_cable" # Reduces boot times through caching; required in config/boot.rb gem "bootsnap", require: false diff --git a/Gemfile.lock b/Gemfile.lock index 7ffa82e..d923c23 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -79,6 +79,7 @@ GEM public_suffix (>= 2.0.2, < 8.0) ast (2.4.3) base64 (0.3.0) + bcrypt (3.1.22) bcrypt_pbkdf (1.1.2) bigdecimal (4.1.2) bindex (0.8.1) @@ -106,6 +107,12 @@ GEM debug (1.11.1) irb (~> 1.10) reline (>= 0.3.8) + devise (5.0.4) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 7.0) + responders + warden (~> 1.2.3) dotenv (3.2.0) drb (2.2.3) ed25519 (1.4.0) @@ -201,6 +208,7 @@ GEM racc (~> 1.4) nokogiri (1.19.4-x86_64-linux-musl) racc (~> 1.4) + orm_adapter (0.5.0) ostruct (0.6.3) parallel (2.1.0) parser (3.3.11.1) @@ -274,6 +282,9 @@ GEM regexp_parser (2.12.0) reline (0.6.3) io-console (~> 0.5) + responders (3.2.1) + actionpack (>= 7.0) + railties (>= 7.0) rexml (3.4.4) rubocop (1.88.1) json (~> 2.3) @@ -364,6 +375,8 @@ GEM unicode-emoji (4.2.0) uri (1.1.1) useragent (0.16.11) + warden (1.2.9) + rack (>= 2.0.9) web-console (4.3.0) actionview (>= 8.0.0) bindex (>= 0.4.0) @@ -395,6 +408,7 @@ DEPENDENCIES bundler-audit capybara debug + devise (~> 5.0) image_processing (~> 2.0) importmap-rails jbuilder @@ -432,6 +446,7 @@ CHECKSUMS addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + bcrypt (3.1.22) sha256=1f0072e88c2d705d94aff7f2c5cb02eb3f1ec4b8368671e19112527489f29032 bcrypt_pbkdf (1.1.2) sha256=c2414c23ce66869b3eb9f643d6a3374d8322dfb5078125c82792304c10b94cf6 bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd bindex (0.8.1) sha256=7b1ecc9dc539ed8bccfc8cb4d2732046227b09d6f37582ff12e50a5047ceb17e @@ -445,6 +460,7 @@ CHECKSUMS crass (1.0.7) sha256=94868719948664c89ddcaf0a37c65048413dfcb1c869470a5f7a7ceb5390b295 date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 + devise (5.0.4) sha256=d605f2b85854e74e56ee789e2d398702bc2d06e6bcd894717a670a3199c74cc1 dotenv (3.2.0) sha256=e375b83121ea7ca4ce20f214740076129ab8514cd81378161f11c03853fe619d drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 @@ -493,6 +509,7 @@ CHECKSUMS nokogiri (1.19.4-arm64-darwin) sha256=a46db9853286e6597b36ebc6953817d15acf3a299583eb3f89fdc6f91dd63527 nokogiri (1.19.4-x86_64-linux-gnu) sha256=379fae440b28915e3f19d752ce2dcf8465ed2b2fbefd2a7ca0dd497bc981a06a nokogiri (1.19.4-x86_64-linux-musl) sha256=17dfb7c1fa194ae02fbf7c51a7afc8d278045ab3fdacfd86f91d02d7b274470b + orm_adapter (0.5.0) sha256=aa5d0be5d540cbb46d3a93e88061f4ece6a25f6e97d6a47122beb84fe595e9b9 ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 parallel (2.1.0) sha256=b35258865c2e31134c5ecb708beaaf6772adf9d5efae28e93e99260877b09356 parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54 @@ -519,6 +536,7 @@ CHECKSUMS rdoc (8.0.0) sha256=03bf8c08a9639658855a0cfd77c0abca8325c227693f7f33f82957811348c469 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 + responders (3.2.1) sha256=c2772970cbda654c0e772d852e5a851e82cd8e96f5fa958650861ba75b8ffa84 rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 rubocop (1.88.1) sha256=726af773d6bc169ed3ff852f3ca020b7c58d39c34e7a8d879a8e0147cc994f26 rubocop-ast (1.50.0) sha256=b9ca88300da0803ee222ad20cdb30494c0a784eed06fdc35d254b06d662788db @@ -555,6 +573,7 @@ CHECKSUMS unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 useragent (0.16.11) sha256=700e6413ad4bb954bb63547fa098dddf7b0ebe75b40cc6f93b8d54255b173844 + warden (1.2.9) sha256=46684f885d35a69dbb883deabf85a222c8e427a957804719e143005df7a1efd0 web-console (4.3.0) sha256=e13b71301cdfc2093f155b5aa3a622db80b4672d1f2f713119cc7ec7ac6a6da4 websocket (1.2.11) sha256=b7e7a74e2410b5e85c25858b26b3322f29161e300935f70a0e0d3c35e0462737 websocket-driver (0.8.2) sha256=97c556b019bf3410b4961002ac501621e9322d3f8a7bc02161a09301cc4c4146 diff --git a/app/assets/images/horse.jpg b/app/assets/images/horse.jpg new file mode 100644 index 0000000..201e1bd Binary files /dev/null and b/app/assets/images/horse.jpg differ diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb new file mode 100644 index 0000000..6396a5f --- /dev/null +++ b/app/controllers/home_controller.rb @@ -0,0 +1,7 @@ +class HomeController < ApplicationController + def index + end + + def world + end +end diff --git a/app/controllers/medication_types_controller.rb b/app/controllers/medication_types_controller.rb new file mode 100644 index 0000000..7bae334 --- /dev/null +++ b/app/controllers/medication_types_controller.rb @@ -0,0 +1,70 @@ +class MedicationTypesController < ApplicationController + before_action :set_medication_type, only: %i[ show edit update destroy ] + + # GET /medication_types or /medication_types.json + def index + @medication_types = MedicationType.all + end + + # GET /medication_types/1 or /medication_types/1.json + def show + end + + # GET /medication_types/new + def new + @medication_type = MedicationType.new + end + + # GET /medication_types/1/edit + def edit + end + + # POST /medication_types or /medication_types.json + def create + @medication_type = MedicationType.new(medication_type_params) + + respond_to do |format| + if @medication_type.save + format.html { redirect_to @medication_type, notice: "Medication type was successfully created." } + format.json { render :show, status: :created, location: @medication_type } + else + format.html { render :new, status: :unprocessable_content } + format.json { render json: @medication_type.errors, status: :unprocessable_content } + end + end + end + + # PATCH/PUT /medication_types/1 or /medication_types/1.json + def update + respond_to do |format| + if @medication_type.update(medication_type_params) + format.html { redirect_to @medication_type, notice: "Medication type was successfully updated.", status: :see_other } + format.json { render :show, status: :ok, location: @medication_type } + else + format.html { render :edit, status: :unprocessable_content } + format.json { render json: @medication_type.errors, status: :unprocessable_content } + end + end + end + + # DELETE /medication_types/1 or /medication_types/1.json + def destroy + @medication_type.destroy! + + respond_to do |format| + format.html { redirect_to medication_types_path, notice: "Medication 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_medication_type + @medication_type = MedicationType.find(params.expect(:id)) + end + + # Only allow a list of trusted parameters through. + def medication_type_params + params.expect(medication_type: [ :name ]) + end +end diff --git a/app/controllers/medications_controller.rb b/app/controllers/medications_controller.rb new file mode 100644 index 0000000..804f765 --- /dev/null +++ b/app/controllers/medications_controller.rb @@ -0,0 +1,70 @@ +class MedicationsController < ApplicationController + before_action :set_medication, only: %i[ show edit update destroy ] + + # GET /medications or /medications.json + def index + @medications = Medication.all + end + + # GET /medications/1 or /medications/1.json + def show + end + + # GET /medications/new + def new + @medication = Medication.new + end + + # GET /medications/1/edit + def edit + end + + # POST /medications or /medications.json + def create + @medication = Medication.new(medication_params) + + respond_to do |format| + if @medication.save + format.html { redirect_to @medication, notice: "Medication was successfully created." } + format.json { render :show, status: :created, location: @medication } + else + format.html { render :new, status: :unprocessable_content } + format.json { render json: @medication.errors, status: :unprocessable_content } + end + end + end + + # PATCH/PUT /medications/1 or /medications/1.json + def update + respond_to do |format| + if @medication.update(medication_params) + format.html { redirect_to @medication, notice: "Medication was successfully updated.", status: :see_other } + format.json { render :show, status: :ok, location: @medication } + else + format.html { render :edit, status: :unprocessable_content } + format.json { render json: @medication.errors, status: :unprocessable_content } + end + end + end + + # DELETE /medications/1 or /medications/1.json + def destroy + @medication.destroy! + + respond_to do |format| + format.html { redirect_to medications_path, notice: "Medication 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_medication + @medication = Medication.find(params.expect(:id)) + end + + # Only allow a list of trusted parameters through. + def medication_params + params.expect(medication: [ :name, :medication_type_id, :current, :dosage, :frequency, :time_of_day, :form, :purpose, :start_date, :stop_date, :refill, :notes ]) + end +end diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb new file mode 100644 index 0000000..f68035c --- /dev/null +++ b/app/controllers/people_controller.rb @@ -0,0 +1,70 @@ +class PeopleController < ApplicationController + before_action :set_person, only: %i[ show edit update destroy ] + + # GET /people or /people.json + def index + @people = Person.all + end + + # GET /people/1 or /people/1.json + def show + end + + # GET /people/new + def new + @person = Person.new + end + + # GET /people/1/edit + def edit + end + + # POST /people or /people.json + def create + @person = Person.new(person_params) + + respond_to do |format| + if @person.save + format.html { redirect_to @person, notice: "Person was successfully created." } + format.json { render :show, status: :created, location: @person } + else + format.html { render :new, status: :unprocessable_content } + format.json { render json: @person.errors, status: :unprocessable_content } + end + end + end + + # PATCH/PUT /people/1 or /people/1.json + def update + respond_to do |format| + if @person.update(person_params) + format.html { redirect_to @person, notice: "Person was successfully updated.", status: :see_other } + format.json { render :show, status: :ok, location: @person } + else + format.html { render :edit, status: :unprocessable_content } + format.json { render json: @person.errors, status: :unprocessable_content } + end + end + end + + # DELETE /people/1 or /people/1.json + def destroy + @person.destroy! + + respond_to do |format| + format.html { redirect_to people_path, notice: "Person 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_person + @person = Person.find(params.expect(:id)) + end + + # Only allow a list of trusted parameters through. + def person_params + params.expect(person: [ :first_name, :last_name, :date_of_birth, :social_security_number, :email, :relationship_id ]) + end +end diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb new file mode 100644 index 0000000..23de56a --- /dev/null +++ b/app/helpers/home_helper.rb @@ -0,0 +1,2 @@ +module HomeHelper +end diff --git a/app/helpers/medication_types_helper.rb b/app/helpers/medication_types_helper.rb new file mode 100644 index 0000000..84a67f0 --- /dev/null +++ b/app/helpers/medication_types_helper.rb @@ -0,0 +1,2 @@ +module MedicationTypesHelper +end diff --git a/app/helpers/medications_helper.rb b/app/helpers/medications_helper.rb new file mode 100644 index 0000000..1cca854 --- /dev/null +++ b/app/helpers/medications_helper.rb @@ -0,0 +1,2 @@ +module MedicationsHelper +end diff --git a/app/helpers/people_helper.rb b/app/helpers/people_helper.rb new file mode 100644 index 0000000..b682fbf --- /dev/null +++ b/app/helpers/people_helper.rb @@ -0,0 +1,2 @@ +module PeopleHelper +end diff --git a/app/models/medication.rb b/app/models/medication.rb new file mode 100644 index 0000000..3527fc1 --- /dev/null +++ b/app/models/medication.rb @@ -0,0 +1,3 @@ +class Medication < ApplicationRecord + belongs_to :medication_type +end diff --git a/app/models/medication_type.rb b/app/models/medication_type.rb new file mode 100644 index 0000000..548d639 --- /dev/null +++ b/app/models/medication_type.rb @@ -0,0 +1,2 @@ +class MedicationType < ApplicationRecord +end diff --git a/app/models/person.rb b/app/models/person.rb new file mode 100644 index 0000000..9791ac6 --- /dev/null +++ b/app/models/person.rb @@ -0,0 +1,3 @@ +class Person < ApplicationRecord + belongs_to :relationship +end diff --git a/app/models/relationship.rb b/app/models/relationship.rb new file mode 100644 index 0000000..3cabc44 --- /dev/null +++ b/app/models/relationship.rb @@ -0,0 +1,2 @@ +class Relationship < ApplicationRecord +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..4f14a8d --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,7 @@ +class User < ApplicationRecord + # Include default devise modules. Others available are: + # :omniauthable + devise :database_authenticatable, :registerable, + :recoverable, :rememberable, :validatable, + :lockable, :trackable, :confirmable +end diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb new file mode 100644 index 0000000..3c21122 --- /dev/null +++ b/app/views/devise/confirmations/new.html.erb @@ -0,0 +1,16 @@ +

Resend confirmation instructions

+ +<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+

<%= f.label :email %>

+

<%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>

+
+ +
+ <%= f.submit "Resend confirmation instructions" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb new file mode 100644 index 0000000..dc55f64 --- /dev/null +++ b/app/views/devise/mailer/confirmation_instructions.html.erb @@ -0,0 +1,5 @@ +

Welcome <%= @email %>!

+ +

You can confirm your account email through the link below:

+ +

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

diff --git a/app/views/devise/mailer/email_changed.html.erb b/app/views/devise/mailer/email_changed.html.erb new file mode 100644 index 0000000..32f4ba8 --- /dev/null +++ b/app/views/devise/mailer/email_changed.html.erb @@ -0,0 +1,7 @@ +

Hello <%= @email %>!

+ +<% if @resource.try(:unconfirmed_email?) %> +

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

+<% else %> +

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

+<% end %> diff --git a/app/views/devise/mailer/password_change.html.erb b/app/views/devise/mailer/password_change.html.erb new file mode 100644 index 0000000..b41daf4 --- /dev/null +++ b/app/views/devise/mailer/password_change.html.erb @@ -0,0 +1,3 @@ +

Hello <%= @resource.email %>!

+ +

We're contacting you to notify you that your password has been changed.

diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb new file mode 100644 index 0000000..f667dc1 --- /dev/null +++ b/app/views/devise/mailer/reset_password_instructions.html.erb @@ -0,0 +1,8 @@ +

Hello <%= @resource.email %>!

+ +

Someone has requested a link to change your password. You can do this through the link below.

+ +

<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>

+ +

If you didn't request this, please ignore this email.

+

Your password won't change until you access the link above and create a new one.

diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb new file mode 100644 index 0000000..41e148b --- /dev/null +++ b/app/views/devise/mailer/unlock_instructions.html.erb @@ -0,0 +1,7 @@ +

Hello <%= @resource.email %>!

+ +

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

+ +

Click the link below to unlock your account:

+ +

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb new file mode 100644 index 0000000..3f1dbc7 --- /dev/null +++ b/app/views/devise/passwords/edit.html.erb @@ -0,0 +1,25 @@ +

Change your password

+ +<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + <%= f.hidden_field :reset_password_token %> + +
+

<%= f.label :password, "New password" %>

+ <% if @minimum_password_length %> +

(<%= @minimum_password_length %> characters minimum)

+ <% end %> +

<%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>

+
+ +
+

<%= f.label :password_confirmation, "Confirm new password" %>

+

<%= f.password_field :password_confirmation, autocomplete: "new-password" %>

+
+ +
+ <%= f.submit "Change my password" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb new file mode 100644 index 0000000..bea7ad1 --- /dev/null +++ b/app/views/devise/passwords/new.html.erb @@ -0,0 +1,16 @@ +

Forgot your password?

+ +<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+

<%= f.label :email %>

+

<%= f.email_field :email, autofocus: true, autocomplete: "email" %>

+
+ +
+ <%= f.submit "Send me password reset instructions" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb new file mode 100644 index 0000000..19bb019 --- /dev/null +++ b/app/views/devise/registrations/edit.html.erb @@ -0,0 +1,42 @@ +

Edit <%= resource_name.to_s.humanize %>

+ +<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+

<%= f.label :email %>

+

<%= f.email_field :email, autofocus: true, autocomplete: "email" %>

+
+ + <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> +
Currently waiting confirmation for: <%= resource.unconfirmed_email %>
+ <% end %> + +
+

<%= f.label :password %> (leave blank if you don't want to change it)

+

<%= f.password_field :password, autocomplete: "new-password" %>

+ <% if @minimum_password_length %> +

<%= @minimum_password_length %> characters minimum

+ <% end %> +
+ +
+

<%= f.label :password_confirmation %>

+

<%= f.password_field :password_confirmation, autocomplete: "new-password" %>

+
+ +
+

<%= f.label :current_password %> (we need your current password to confirm your changes)

+

<%= f.password_field :current_password, autocomplete: "current-password" %>

+
+ +
+ <%= f.submit "Update" %> +
+<% end %> + +

Cancel my account

+ +
Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %>
+ +<%= link_to "Back", :back %> diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb new file mode 100644 index 0000000..03f48fb --- /dev/null +++ b/app/views/devise/registrations/new.html.erb @@ -0,0 +1,29 @@ +

Sign up

+ +<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+

<%= f.label :email %>

+

<%= f.email_field :email, autofocus: true, autocomplete: "email" %>

+
+ +
+

<%= f.label :password %>

+ <% if @minimum_password_length %> +

(<%= @minimum_password_length %> characters minimum)

+ <% end %> +

<%= f.password_field :password, autocomplete: "new-password" %>

+
+ +
+

<%= f.label :password_confirmation %>

+

<%= f.password_field :password_confirmation, autocomplete: "new-password" %>

+
+ +
+ <%= f.submit "Sign up" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb new file mode 100644 index 0000000..6eeb9fc --- /dev/null +++ b/app/views/devise/sessions/new.html.erb @@ -0,0 +1,26 @@ +

Log in

+ +<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> +
+

<%= f.label :email %>

+

<%= f.email_field :email, autofocus: true, autocomplete: "email" %>

+
+ +
+

<%= f.label :password %>

+

<%= f.password_field :password, autocomplete: "current-password" %>

+
+ + <% if devise_mapping.rememberable? %> +
+

<%= f.check_box :remember_me %>

+

<%= f.label :remember_me %>

+
+ <% end %> + +
+ <%= f.submit "Log in" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/shared/_error_messages.html.erb b/app/views/devise/shared/_error_messages.html.erb new file mode 100644 index 0000000..8c9c171 --- /dev/null +++ b/app/views/devise/shared/_error_messages.html.erb @@ -0,0 +1,15 @@ +<% if resource.errors.any? %> +
+

+ <%= I18n.t("errors.messages.not_saved", + count: resource.errors.count, + resource: resource.class.model_name.human.downcase) + %> +

+ +
+<% end %> diff --git a/app/views/devise/shared/_links.html.erb b/app/views/devise/shared/_links.html.erb new file mode 100644 index 0000000..21cf422 --- /dev/null +++ b/app/views/devise/shared/_links.html.erb @@ -0,0 +1,25 @@ +<%- if controller_name != 'sessions' %> +

<%= link_to "Log in", new_session_path(resource_name) %>

+<% end %> + +<%- if devise_mapping.registerable? && controller_name != 'registrations' %> +

<%= link_to "Sign up", new_registration_path(resource_name) %>

+<% end %> + +<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> +

<%= link_to "Forgot your password?", new_password_path(resource_name) %>

+<% end %> + +<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> +

<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>

+<% end %> + +<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> +

<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>

+<% end %> + +<%- if devise_mapping.omniauthable? %> + <%- resource_class.omniauth_providers.each do |provider| %> +

<%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %>

+ <% end %> +<% end %> diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb new file mode 100644 index 0000000..6b68d72 --- /dev/null +++ b/app/views/devise/unlocks/new.html.erb @@ -0,0 +1,16 @@ +

Resend unlock instructions

+ +<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+

<%= f.label :email %>

+

<%= f.email_field :email, autofocus: true, autocomplete: "email" %>

+
+ +
+ <%= f.submit "Resend unlock instructions" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb new file mode 100644 index 0000000..3485ac1 --- /dev/null +++ b/app/views/home/index.html.erb @@ -0,0 +1,11 @@ +

heading

+

Hi

+<%= image_tag "horse.jpg", alt: "Horse", class: "horse-image" %> + +<% if user_signed_in? %> +

<%= link_to 'Sign out', destroy_user_session_path, data: { turbo_method: :delete } %>

+<% else %> +

<%= link_to 'Sign in', new_user_session_path %>

+

<%= link_to 'Sign up', new_user_registration_path %>

+<% end %> + diff --git a/app/views/medication_types/_form.html.erb b/app/views/medication_types/_form.html.erb new file mode 100644 index 0000000..3fd2f7b --- /dev/null +++ b/app/views/medication_types/_form.html.erb @@ -0,0 +1,22 @@ +<%= form_with(model: medication_type) do |form| %> + <% if medication_type.errors.any? %> +
+

<%= pluralize(medication_type.errors.count, "error") %> prohibited this medication_type from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :name, style: "display: block" %> + <%= form.text_field :name %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/medication_types/_medication_type.html.erb b/app/views/medication_types/_medication_type.html.erb new file mode 100644 index 0000000..6b97951 --- /dev/null +++ b/app/views/medication_types/_medication_type.html.erb @@ -0,0 +1,7 @@ +
+
+ Name: + <%= medication_type.name %> +
+ +
diff --git a/app/views/medication_types/_medication_type.json.jbuilder b/app/views/medication_types/_medication_type.json.jbuilder new file mode 100644 index 0000000..b8273fa --- /dev/null +++ b/app/views/medication_types/_medication_type.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! medication_type, :id, :name, :created_at, :updated_at +json.url medication_type_url(medication_type, format: :json) diff --git a/app/views/medication_types/edit.html.erb b/app/views/medication_types/edit.html.erb new file mode 100644 index 0000000..de94f6c --- /dev/null +++ b/app/views/medication_types/edit.html.erb @@ -0,0 +1,12 @@ +<% content_for :title, "Editing medication type" %> + +

Editing medication type

+ +<%= render "form", medication_type: @medication_type %> + +
+ +
+ <%= link_to "Show this medication type", @medication_type %> | + <%= link_to "Back to medication types", medication_types_path %> +
diff --git a/app/views/medication_types/index.html.erb b/app/views/medication_types/index.html.erb new file mode 100644 index 0000000..ef7c687 --- /dev/null +++ b/app/views/medication_types/index.html.erb @@ -0,0 +1,16 @@ +

<%= notice %>

+ +<% content_for :title, "Medication types" %> + +

Medication types

+ +
+ <% @medication_types.each do |medication_type| %> + <%= render medication_type %> +

+ <%= link_to "Show this medication type", medication_type %> +

+ <% end %> +
+ +<%= link_to "New medication type", new_medication_type_path %> diff --git a/app/views/medication_types/index.json.jbuilder b/app/views/medication_types/index.json.jbuilder new file mode 100644 index 0000000..699339e --- /dev/null +++ b/app/views/medication_types/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @medication_types, partial: "medication_types/medication_type", as: :medication_type diff --git a/app/views/medication_types/new.html.erb b/app/views/medication_types/new.html.erb new file mode 100644 index 0000000..14c0467 --- /dev/null +++ b/app/views/medication_types/new.html.erb @@ -0,0 +1,11 @@ +<% content_for :title, "New medication type" %> + +

New medication type

+ +<%= render "form", medication_type: @medication_type %> + +
+ +
+ <%= link_to "Back to medication types", medication_types_path %> +
diff --git a/app/views/medication_types/show.html.erb b/app/views/medication_types/show.html.erb new file mode 100644 index 0000000..7ec776e --- /dev/null +++ b/app/views/medication_types/show.html.erb @@ -0,0 +1,10 @@ +

<%= notice %>

+ +<%= render @medication_type %> + +
+ <%= link_to "Edit this medication type", edit_medication_type_path(@medication_type) %> | + <%= link_to "Back to medication types", medication_types_path %> + + <%= button_to "Destroy this medication type", @medication_type, method: :delete %> +
diff --git a/app/views/medication_types/show.json.jbuilder b/app/views/medication_types/show.json.jbuilder new file mode 100644 index 0000000..b175477 --- /dev/null +++ b/app/views/medication_types/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "medication_types/medication_type", medication_type: @medication_type diff --git a/app/views/medications/_form.html.erb b/app/views/medications/_form.html.erb new file mode 100644 index 0000000..678d8b6 --- /dev/null +++ b/app/views/medications/_form.html.erb @@ -0,0 +1,77 @@ +<%= form_with(model: medication) do |form| %> + <% if medication.errors.any? %> +
+

<%= pluralize(medication.errors.count, "error") %> prohibited this medication from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :name, style: "display: block" %> + <%= form.text_field :name %> +
+ +
+ <%= form.label :medication_type_id, style: "display: block" %> + <%= form.text_field :medication_type_id %> +
+ +
+ <%= form.label :current, style: "display: block" %> + <%= form.checkbox :current %> +
+ +
+ <%= form.label :dosage, style: "display: block" %> + <%= form.text_field :dosage %> +
+ +
+ <%= form.label :frequency, style: "display: block" %> + <%= form.text_field :frequency %> +
+ +
+ <%= form.label :time_of_day, style: "display: block" %> + <%= form.text_field :time_of_day %> +
+ +
+ <%= form.label :form, style: "display: block" %> + <%= form.text_field :form %> +
+ +
+ <%= form.label :purpose, style: "display: block" %> + <%= form.textarea :purpose %> +
+ +
+ <%= form.label :start_date, style: "display: block" %> + <%= form.date_field :start_date %> +
+ +
+ <%= form.label :stop_date, style: "display: block" %> + <%= form.date_field :stop_date %> +
+ +
+ <%= form.label :refill, style: "display: block" %> + <%= form.text_field :refill %> +
+ +
+ <%= form.label :notes, style: "display: block" %> + <%= form.textarea :notes %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/medications/_medication.html.erb b/app/views/medications/_medication.html.erb new file mode 100644 index 0000000..9d4de65 --- /dev/null +++ b/app/views/medications/_medication.html.erb @@ -0,0 +1,62 @@ +
+
+ Name: + <%= medication.name %> +
+ +
+ Medication type: + <%= medication.medication_type_id %> +
+ +
+ Current: + <%= medication.current %> +
+ +
+ Dosage: + <%= medication.dosage %> +
+ +
+ Frequency: + <%= medication.frequency %> +
+ +
+ Time of day: + <%= medication.time_of_day %> +
+ +
+ Form: + <%= medication.form %> +
+ +
+ Purpose: + <%= medication.purpose %> +
+ +
+ Start date: + <%= medication.start_date %> +
+ +
+ Stop date: + <%= medication.stop_date %> +
+ +
+ Refill: + <%= medication.refill %> +
+ +
+ Notes: + <%= medication.notes %> +
+ +
diff --git a/app/views/medications/_medication.json.jbuilder b/app/views/medications/_medication.json.jbuilder new file mode 100644 index 0000000..7035a68 --- /dev/null +++ b/app/views/medications/_medication.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! medication, :id, :name, :medication_type_id, :current, :dosage, :frequency, :time_of_day, :form, :purpose, :start_date, :stop_date, :refill, :notes, :created_at, :updated_at +json.url medication_url(medication, format: :json) diff --git a/app/views/medications/edit.html.erb b/app/views/medications/edit.html.erb new file mode 100644 index 0000000..501cf0d --- /dev/null +++ b/app/views/medications/edit.html.erb @@ -0,0 +1,12 @@ +<% content_for :title, "Editing medication" %> + +

Editing medication

+ +<%= render "form", medication: @medication %> + +
+ +
+ <%= link_to "Show this medication", @medication %> | + <%= link_to "Back to medications", medications_path %> +
diff --git a/app/views/medications/index.html.erb b/app/views/medications/index.html.erb new file mode 100644 index 0000000..af091f8 --- /dev/null +++ b/app/views/medications/index.html.erb @@ -0,0 +1,16 @@ +

<%= notice %>

+ +<% content_for :title, "Medications" %> + +

Medications

+ +
+ <% @medications.each do |medication| %> + <%= render medication %> +

+ <%= link_to "Show this medication", medication %> +

+ <% end %> +
+ +<%= link_to "New medication", new_medication_path %> diff --git a/app/views/medications/index.json.jbuilder b/app/views/medications/index.json.jbuilder new file mode 100644 index 0000000..fa6c129 --- /dev/null +++ b/app/views/medications/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @medications, partial: "medications/medication", as: :medication diff --git a/app/views/medications/new.html.erb b/app/views/medications/new.html.erb new file mode 100644 index 0000000..64c6d1c --- /dev/null +++ b/app/views/medications/new.html.erb @@ -0,0 +1,11 @@ +<% content_for :title, "New medication" %> + +

New medication

+ +<%= render "form", medication: @medication %> + +
+ +
+ <%= link_to "Back to medications", medications_path %> +
diff --git a/app/views/medications/show.html.erb b/app/views/medications/show.html.erb new file mode 100644 index 0000000..603914f --- /dev/null +++ b/app/views/medications/show.html.erb @@ -0,0 +1,10 @@ +

<%= notice %>

+ +<%= render @medication %> + +
+ <%= link_to "Edit this medication", edit_medication_path(@medication) %> | + <%= link_to "Back to medications", medications_path %> + + <%= button_to "Destroy this medication", @medication, method: :delete %> +
diff --git a/app/views/medications/show.json.jbuilder b/app/views/medications/show.json.jbuilder new file mode 100644 index 0000000..b2ae681 --- /dev/null +++ b/app/views/medications/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "medications/medication", medication: @medication diff --git a/app/views/people/_form.html.erb b/app/views/people/_form.html.erb new file mode 100644 index 0000000..0d19245 --- /dev/null +++ b/app/views/people/_form.html.erb @@ -0,0 +1,47 @@ +<%= form_with(model: person) do |form| %> + <% if person.errors.any? %> +
+

<%= pluralize(person.errors.count, "error") %> prohibited this person from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :first_name, style: "display: block" %> + <%= form.text_field :first_name %> +
+ +
+ <%= form.label :last_name, style: "display: block" %> + <%= form.text_field :last_name %> +
+ +
+ <%= form.label :date_of_birth, style: "display: block" %> + <%= form.date_field :date_of_birth %> +
+ +
+ <%= form.label :social_security_number, style: "display: block" %> + <%= form.text_field :social_security_number %> +
+ +
+ <%= form.label :email, style: "display: block" %> + <%= form.text_field :email %> +
+ +
+ <%= form.label :relationship_id, style: "display: block" %> + <%= form.text_field :relationship_id %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/people/_person.html.erb b/app/views/people/_person.html.erb new file mode 100644 index 0000000..36f544d --- /dev/null +++ b/app/views/people/_person.html.erb @@ -0,0 +1,32 @@ +
+
+ First name: + <%= person.first_name %> +
+ +
+ Last name: + <%= person.last_name %> +
+ +
+ Date of birth: + <%= person.date_of_birth %> +
+ +
+ Social security number: + <%= person.social_security_number %> +
+ +
+ Email: + <%= person.email %> +
+ +
+ Relationship: + <%= person.relationship_id %> +
+ +
diff --git a/app/views/people/_person.json.jbuilder b/app/views/people/_person.json.jbuilder new file mode 100644 index 0000000..95ae139 --- /dev/null +++ b/app/views/people/_person.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! person, :id, :first_name, :last_name, :date_of_birth, :social_security_number, :email, :relationship_id, :created_at, :updated_at +json.url person_url(person, format: :json) diff --git a/app/views/people/edit.html.erb b/app/views/people/edit.html.erb new file mode 100644 index 0000000..82fbae5 --- /dev/null +++ b/app/views/people/edit.html.erb @@ -0,0 +1,12 @@ +<% content_for :title, "Editing person" %> + +

Editing person

+ +<%= render "form", person: @person %> + +
+ +
+ <%= link_to "Show this person", @person %> | + <%= link_to "Back to people", people_path %> +
diff --git a/app/views/people/index.html.erb b/app/views/people/index.html.erb new file mode 100644 index 0000000..c4611fb --- /dev/null +++ b/app/views/people/index.html.erb @@ -0,0 +1,16 @@ +

<%= notice %>

+ +<% content_for :title, "People" %> + +

People

+ +
+ <% @people.each do |person| %> + <%= render person %> +

+ <%= link_to "Show this person", person %> +

+ <% end %> +
+ +<%= link_to "New person", new_person_path %> diff --git a/app/views/people/index.json.jbuilder b/app/views/people/index.json.jbuilder new file mode 100644 index 0000000..14d7899 --- /dev/null +++ b/app/views/people/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @people, partial: "people/person", as: :person diff --git a/app/views/people/new.html.erb b/app/views/people/new.html.erb new file mode 100644 index 0000000..d26f879 --- /dev/null +++ b/app/views/people/new.html.erb @@ -0,0 +1,11 @@ +<% content_for :title, "New person" %> + +

New person

+ +<%= render "form", person: @person %> + +
+ +
+ <%= link_to "Back to people", people_path %> +
diff --git a/app/views/people/show.html.erb b/app/views/people/show.html.erb new file mode 100644 index 0000000..5fa7251 --- /dev/null +++ b/app/views/people/show.html.erb @@ -0,0 +1,10 @@ +

<%= notice %>

+ +<%= render @person %> + +
+ <%= link_to "Edit this person", edit_person_path(@person) %> | + <%= link_to "Back to people", people_path %> + + <%= button_to "Destroy this person", @person, method: :delete %> +
diff --git a/app/views/people/show.json.jbuilder b/app/views/people/show.json.jbuilder new file mode 100644 index 0000000..cf0f817 --- /dev/null +++ b/app/views/people/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "people/person", person: @person diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb new file mode 100644 index 0000000..1c2def7 --- /dev/null +++ b/config/initializers/devise.rb @@ -0,0 +1,316 @@ +# frozen_string_literal: true + +# Assuming you have not yet modified this file, each configuration option below +# is set to its default value. Note that some are commented out while others +# are not: uncommented lines are intended to protect your configuration from +# breaking changes in upgrades (i.e., in the event that future versions of +# Devise change the default values for those options). +# +# Use this hook to configure devise mailer, warden hooks and so forth. +# Many of these configuration options can be set straight in your model. +Devise.setup do |config| + # The secret key used by Devise. Devise uses this key to generate + # random tokens. Changing this key will render invalid all existing + # confirmation, reset password and unlock tokens in the database. + # Devise will use the `secret_key_base` as its `secret_key` + # by default. You can change it below and use your own secret key. + # config.secret_key = 'be48cc765be7e2ec33ba15d2a1fbdac62ecd68ea971d1294f8bfaf1dc502921adcbb9a42180741dfe89dccc80c2a1d9d4943cc6c288ce8a6443cb404505e22b3' + + # ==> Controller configuration + # Configure the parent class to the devise controllers. + # config.parent_controller = 'DeviseController' + + # ==> Mailer Configuration + # Configure the e-mail address which will be shown in Devise::Mailer, + # note that it will be overwritten if you use your own mailer class + # with default "from" parameter. + config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com" + + # Configure the class responsible to send e-mails. + # config.mailer = 'Devise::Mailer' + + # Configure the parent class responsible to send e-mails. + # config.parent_mailer = 'ActionMailer::Base' + + # ==> ORM configuration + # Load and configure the ORM. Supports :active_record (default) and + # :mongoid (bson_ext recommended) by default. Other ORMs may be + # available as additional gems. + require "devise/orm/active_record" + + # ==> Configuration for any authentication mechanism + # Configure which keys are used when authenticating a user. The default is + # just :email. You can configure it to use [:username, :subdomain], so for + # authenticating a user, both parameters are required. Remember that those + # parameters are used only when authenticating and not when retrieving from + # session. If you need permissions, you should implement that in a before filter. + # You can also supply a hash where the value is a boolean determining whether + # or not authentication should be aborted when the value is not present. + # config.authentication_keys = [:email] + + # Configure parameters from the request object used for authentication. Each entry + # given should be a request method and it will automatically be passed to the + # find_for_authentication method and considered in your model lookup. For instance, + # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. + # The same considerations mentioned for authentication_keys also apply to request_keys. + # config.request_keys = [] + + # Configure which authentication keys should be case-insensitive. + # These keys will be downcased upon creating or modifying a user and when used + # to authenticate or find a user. Default is :email. + config.case_insensitive_keys = [ :email ] + + # Configure which authentication keys should have whitespace stripped. + # These keys will have whitespace before and after removed upon creating or + # modifying a user and when used to authenticate or find a user. Default is :email. + config.strip_whitespace_keys = [ :email ] + + # Tell if authentication through request.params is enabled. True by default. + # It can be set to an array that will enable params authentication only for the + # given strategies, for example, `config.params_authenticatable = [:database]` will + # enable it only for database (email + password) authentication. + # config.params_authenticatable = true + + # Tell if authentication through HTTP Auth is enabled. False by default. + # It can be set to an array that will enable http authentication only for the + # given strategies, for example, `config.http_authenticatable = [:database]` will + # enable it only for database authentication. + # For API-only applications to support authentication "out-of-the-box", you will likely want to + # enable this with :database unless you are using a custom strategy. + # The supported strategies are: + # :database = Support basic authentication with authentication key + password + # config.http_authenticatable = false + + # If 401 status code should be returned for AJAX requests. True by default. + # config.http_authenticatable_on_xhr = true + + # The realm used in Http Basic Authentication. 'Application' by default. + # config.http_authentication_realm = 'Application' + + # It will change confirmation, password recovery and other workflows + # to behave the same regardless if the e-mail provided was right or wrong. + # Does not affect registerable. + # config.paranoid = true + + # By default Devise will store the user in session. You can skip storage for + # particular strategies by setting this option. + # Notice that if you are skipping storage for all authentication paths, you + # may want to disable generating routes to Devise's sessions controller by + # passing skip: :sessions to `devise_for` in your config/routes.rb + config.skip_session_storage = [ :http_auth ] + + # By default, Devise cleans up the CSRF token on authentication to + # avoid CSRF token fixation attacks. This means that, when using AJAX + # requests for sign in and sign up, you need to get a new CSRF token + # from the server. You can disable this option at your own risk. + # config.clean_up_csrf_token_on_authentication = true + + # When false, Devise will not attempt to reload routes on eager load. + # This can reduce the time taken to boot the app but if your application + # requires the Devise mappings to be loaded during boot time the application + # won't boot properly. + # config.reload_routes = true + + # ==> Configuration for :database_authenticatable + # For bcrypt, this is the cost for hashing the password and defaults to 12. If + # using other algorithms, it sets how many times you want the password to be hashed. + # The number of stretches used for generating the hashed password are stored + # with the hashed password. This allows you to change the stretches without + # invalidating existing passwords. + # + # Limiting the stretches to just one in testing will increase the performance of + # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use + # a value less than 10 in other environments. Note that, for bcrypt (the default + # algorithm), the cost increases exponentially with the number of stretches (e.g. + # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). + config.stretches = Rails.env.test? ? 1 : 12 + + # Set up a pepper to generate the hashed password. + # config.pepper = '127706bcb62f32c2160abb282491c2810ecf01a418769b330824734bb3a5bbf935ef806c4f977db9681c9aaa31c01e773ee372c40f94b5326690c7d9c7c37c6b' + + # Send a notification to the original email when the user's email is changed. + # config.send_email_changed_notification = false + + # Send a notification email when the user's password is changed. + # config.send_password_change_notification = false + + # ==> Configuration for :confirmable + # A period that the user is allowed to access the website even without + # confirming their account. For instance, if set to 2.days, the user will be + # able to access the website for two days without confirming their account, + # access will be blocked just in the third day. + # You can also set it to nil, which will allow the user to access the website + # without confirming their account. + # Default is 0.days, meaning the user cannot access the website without + # confirming their account. + config.allow_unconfirmed_access_for = nil + + # A period that the user is allowed to confirm their account before their + # token becomes invalid. For example, if set to 3.days, the user can confirm + # their account within 3 days after the mail was sent, but on the fourth day + # their account can't be confirmed with the token any more. + # Default is nil, meaning there is no restriction on how long a user can take + # before confirming their account. + # config.confirm_within = 3.days + + # If true, requires any email changes to be confirmed (exactly the same way as + # initial account confirmation) to be applied. Requires additional unconfirmed_email + # db field (see migrations). Until confirmed, new email is stored in + # unconfirmed_email column, and copied to email column on successful confirmation. + # Also, when used in conjunction with `send_email_changed_notification`, + # the notification is sent to the original email when the change is requested, + # not when the unconfirmed email is confirmed. + config.reconfirmable = true + + # Defines which key will be used when confirming an account + # config.confirmation_keys = [:email] + + # ==> Configuration for :rememberable + # The time the user will be remembered without asking for credentials again. + # config.remember_for = 2.weeks + + # Invalidates all the remember me tokens when the user signs out. + config.expire_all_remember_me_on_sign_out = true + + # If true, extends the user's remember period when remembered via cookie. + # config.extend_remember_period = false + + # Options to be passed to the created cookie. For instance, you can set + # secure: true in order to force SSL only cookies. + # config.rememberable_options = {} + + # ==> Configuration for :validatable + # Range for password length. + config.password_length = 6..128 + + # Email regex used to validate email formats. It simply asserts that + # one (and only one) @ exists in the given string. This is mainly + # to give user feedback and not to assert the e-mail validity. + config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ + + # ==> Configuration for :timeoutable + # The time you want to timeout the user session without activity. After this + # time the user will be asked for credentials again. Default is 30 minutes. + # config.timeout_in = 30.minutes + + # ==> Configuration for :lockable + # Defines which strategy will be used to lock an account. + # :failed_attempts = Locks an account after a number of failed attempts to sign in. + # :none = No lock strategy. You should handle locking by yourself. + # config.lock_strategy = :failed_attempts + + # Defines which key will be used when locking and unlocking an account + # config.unlock_keys = [:email] + + # Defines which strategy will be used to unlock an account. + # :email = Sends an unlock link to the user email + # :time = Re-enables login after a certain amount of time (see :unlock_in below) + # :both = Enables both strategies + # :none = No unlock strategy. You should handle unlocking by yourself. + # config.unlock_strategy = :both + + # Number of authentication tries before locking an account if lock_strategy + # is failed attempts. + # config.maximum_attempts = 20 + + # Time interval to unlock the account if :time is enabled as unlock_strategy. + # config.unlock_in = 1.hour + + # Warn on the last attempt before the account is locked. + # config.last_attempt_warning = true + + # ==> Configuration for :recoverable + # + # Defines which key will be used when recovering the password for an account + config.reset_password_keys = [:email] + + # Time interval you can reset your password with a reset password key. + # Don't put a too small interval or your users won't have the time to + # change their passwords. + config.reset_password_within = 6.hours + + # When set to false, does not sign a user in automatically after their password is + # reset. Defaults to true, so a user is signed in automatically after a reset. + # config.sign_in_after_reset_password = true + + # ==> Configuration for :encryptable + # Allow you to use another hashing or encryption algorithm besides bcrypt (default). + # You can use :sha1, :sha512 or algorithms from others authentication tools as + # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20 + # for default behavior) and :restful_authentication_sha1 (then you should set + # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper). + # + # Require the `devise-encryptable` gem when using anything other than bcrypt + # config.encryptor = :sha512 + + # ==> Scopes configuration + # Turn scoped views on. Before rendering "sessions/new", it will first check for + # "users/sessions/new". It's turned off by default because it's slower if you + # are using only default views. + # config.scoped_views = false + + # Configure the default scope given to Warden. By default it's the first + # devise role declared in your routes (usually :user). + # config.default_scope = :user + + # Set this configuration to false if you want /users/sign_out to sign out + # only the current scope. By default, Devise signs out all scopes. + # config.sign_out_all_scopes = true + + # ==> Navigation configuration + # Lists the formats that should be treated as navigational. Formats like + # :html should redirect to the sign in page when the user does not have + # access, but formats like :xml or :json, should return 401. + # + # If you have any extra navigational formats, like :iphone or :mobile, you + # should add them to the navigational formats lists. + # + # The "*/*" below is required to match Internet Explorer requests. + # config.navigational_formats = ['*/*', :html, :turbo_stream] + + # The default HTTP method used to sign out a resource. Default is :delete. + config.sign_out_via = :delete + + # ==> OmniAuth + # Add a new OmniAuth provider. Check the wiki for more information on setting + # up on your models and hooks. + # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' + + # ==> Warden configuration + # If you want to use other strategies, that are not supported by Devise, or + # change the failure app, you can configure them inside the config.warden block. + # + # config.warden do |warden_config| + # warden_config.intercept_401 = false + # warden_config.default_strategies(scope: :user).unshift :some_external_strategy + # end + + # ==> Mountable engine configurations + # When using Devise inside an engine, let's call it `MyEngine`, and this engine + # is mountable, there are some extra configurations to be taken into account. + # The following options are available, assuming the engine is mounted as: + # + # mount MyEngine, at: '/my_engine' + # + # The router that invoked `devise_for`, in the example above, would be: + # config.router_name = :my_engine + # + # When using OmniAuth, Devise cannot automatically set OmniAuth path, + # so you need to do it manually. For the users scope, it would be: + # config.omniauth_path_prefix = '/my_engine/users/auth' + + # ==> Hotwire/Turbo configuration + # When using Devise with Hotwire/Turbo, the http status for error responses + # and some redirects must match the following. The default in Devise for existing + # apps is `200 OK` and `302 Found` respectively, but new apps are generated with + # these new defaults that match Hotwire/Turbo behavior. + # Note: These might become the new default in future versions of Devise. + config.responder.error_status = :unprocessable_content + config.responder.redirect_status = :see_other + + # ==> Configuration for :registerable + + # When set to false, does not sign a user in automatically after their password is + # changed. Defaults to true, so a user is signed in automatically after changing a password. + config.sign_in_after_change_password = true +end diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml new file mode 100644 index 0000000..260e1c4 --- /dev/null +++ b/config/locales/devise.en.yml @@ -0,0 +1,65 @@ +# Additional translations at https://github.com/heartcombo/devise/wiki/I18n + +en: + devise: + confirmations: + confirmed: "Your email address has been successfully confirmed." + send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes." + failure: + already_authenticated: "You are already signed in." + inactive: "Your account is not activated yet." + invalid: "Invalid %{authentication_keys} or password." + locked: "Your account is locked." + last_attempt: "You have one more attempt before your account is locked." + not_found_in_database: "Invalid %{authentication_keys} or password." + timeout: "Your session expired. Please sign in again to continue." + unauthenticated: "You need to sign in or sign up before continuing." + unconfirmed: "You have to confirm your email address before continuing." + mailer: + confirmation_instructions: + subject: "Confirmation instructions" + reset_password_instructions: + subject: "Reset password instructions" + unlock_instructions: + subject: "Unlock instructions" + email_changed: + subject: "Email Changed" + password_change: + subject: "Password Changed" + omniauth_callbacks: + failure: "Could not authenticate you from %{kind} because \"%{reason}\"." + success: "Successfully authenticated from %{kind} account." + passwords: + no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided." + send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." + updated: "Your password has been changed successfully. You are now signed in." + updated_not_active: "Your password has been changed successfully." + registrations: + destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon." + signed_up: "Welcome! You have signed up successfully." + signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." + signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." + signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account." + update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address." + updated: "Your account has been updated successfully." + updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again." + sessions: + signed_in: "Signed in successfully." + signed_out: "Signed out successfully." + already_signed_out: "Signed out successfully." + unlocks: + send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes." + send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes." + unlocked: "Your account has been unlocked successfully. Please sign in to continue." + errors: + messages: + already_confirmed: "was already confirmed, please try signing in" + confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" + expired: "has expired, please request a new one" + not_found: "not found" + not_locked: "was not locked" + not_saved: + one: "1 error prohibited this %{resource} from being saved:" + other: "%{count} errors prohibited this %{resource} from being saved:" diff --git a/config/routes.rb b/config/routes.rb index 4368cb6..499ad5c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,8 @@ Rails.application.routes.draw do + devise_for :users + resources :medications + resources :medication_types + resources :people # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # JSON API consumed by the Expo app in mobile/. @@ -24,5 +28,6 @@ # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker # Defines the root path route ("/") - # root "posts#index" + root "home#index" + get "world" => "home#world" end diff --git a/db/migrate/20260828183715_create_people.rb b/db/migrate/20260828183715_create_people.rb new file mode 100644 index 0000000..159c2c8 --- /dev/null +++ b/db/migrate/20260828183715_create_people.rb @@ -0,0 +1,14 @@ +class CreatePeople < ActiveRecord::Migration[8.1] + def change + create_table :people do |t| + t.string :first_name + t.string :last_name + t.date :date_of_birth + t.string :social_security_number + t.string :email + t.belongs_to :relationship, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/migrate/20260828184216_create_medication_types.rb b/db/migrate/20260828184216_create_medication_types.rb new file mode 100644 index 0000000..9a71d5d --- /dev/null +++ b/db/migrate/20260828184216_create_medication_types.rb @@ -0,0 +1,9 @@ +class CreateMedicationTypes < ActiveRecord::Migration[8.1] + def change + create_table :medication_types do |t| + t.string :name + + t.timestamps + end + end +end diff --git a/db/migrate/20260828193338_devise_create_users.rb b/db/migrate/20260828193338_devise_create_users.rb new file mode 100644 index 0000000..b237e7a --- /dev/null +++ b/db/migrate/20260828193338_devise_create_users.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +class DeviseCreateUsers < ActiveRecord::Migration[8.1] + def change + create_table :users do |t| + ## Database authenticatable + t.string :email, null: false + t.string :encrypted_password, null: false + + ## Recoverable + t.string :reset_password_token + t.datetime :reset_password_sent_at + + ## Rememberable + t.datetime :remember_created_at + + ## Trackable + t.integer :sign_in_count, default: 0, null: false + t.datetime :current_sign_in_at + t.datetime :last_sign_in_at + t.string :current_sign_in_ip + t.string :last_sign_in_ip + + ## Confirmable + t.string :confirmation_token + t.datetime :confirmed_at + t.datetime :confirmation_sent_at + t.string :unconfirmed_email # Only if using reconfirmable + + ## Lockable + t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts + t.string :unlock_token # Only if unlock strategy is :email or :both + t.datetime :locked_at + + + t.timestamps null: false + end + + add_index :users, :email, unique: true + add_index :users, :reset_password_token, unique: true + add_index :users, :confirmation_token, unique: true + add_index :users, :unlock_token, unique: true + end +end diff --git a/db/migrate/20260829113658_create_medications.rb b/db/migrate/20260829113658_create_medications.rb new file mode 100644 index 0000000..613848b --- /dev/null +++ b/db/migrate/20260829113658_create_medications.rb @@ -0,0 +1,20 @@ +class CreateMedications < ActiveRecord::Migration[8.1] + def change + create_table :medications do |t| + t.string :name + t.belongs_to :medication_type, null: false, foreign_key: true + t.boolean :current + t.string :dosage + t.string :frequency + t.string :time_of_day + t.string :form + t.text :purpose + t.date :start_date + t.date :stop_date + t.string :refill + t.text :notes + + t.timestamps + end + end +end diff --git a/db/migrate/20260829113836_create_relationships.rb b/db/migrate/20260829113836_create_relationships.rb new file mode 100644 index 0000000..e81702b --- /dev/null +++ b/db/migrate/20260829113836_create_relationships.rb @@ -0,0 +1,9 @@ +class CreateRelationships < ActiveRecord::Migration[8.1] + def change + create_table :relationships do |t| + t.string :name + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 8e5e9b6..c2e519c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,11 +10,82 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.1].define(version: 2026_08_02_160512) do +ActiveRecord::Schema[8.1].define(version: 2026_08_29_113836) do + create_table "medication_types", force: :cascade do |t| + t.datetime "created_at", null: false + t.string "name" + t.datetime "updated_at", null: false + end + + create_table "medications", force: :cascade do |t| + t.datetime "created_at", null: false + t.boolean "current" + t.string "dosage" + t.string "form" + t.string "frequency" + t.integer "medication_type_id", null: false + t.string "name" + t.text "notes" + t.text "purpose" + t.string "refill" + t.date "start_date" + t.date "stop_date" + t.string "time_of_day" + t.datetime "updated_at", null: false + t.index ["medication_type_id"], name: "index_medications_on_medication_type_id" + end + + create_table "people", force: :cascade do |t| + t.datetime "created_at", null: false + t.date "date_of_birth" + t.string "email" + t.string "first_name" + t.string "last_name" + t.integer "relationship_id", null: false + t.string "social_security_number" + t.datetime "updated_at", null: false + t.index ["relationship_id"], name: "index_people_on_relationship_id" + end + + create_table "relationships", force: :cascade do |t| + t.datetime "created_at", null: false + t.string "name" + t.datetime "updated_at", null: false + end + create_table "tasks", force: :cascade do |t| t.boolean "completed", default: false, null: false t.datetime "created_at", null: false t.string "title", null: false t.datetime "updated_at", null: false end + + create_table "users", force: :cascade do |t| + t.datetime "confirmation_sent_at" + t.string "confirmation_token" + t.datetime "confirmed_at" + t.datetime "created_at", null: false + t.datetime "current_sign_in_at" + t.string "current_sign_in_ip" + t.string "email", null: false + t.string "encrypted_password", null: false + t.integer "failed_attempts", default: 0, null: false + t.datetime "last_sign_in_at" + t.string "last_sign_in_ip" + t.datetime "locked_at" + t.datetime "remember_created_at" + t.datetime "reset_password_sent_at" + t.string "reset_password_token" + t.integer "sign_in_count", default: 0, null: false + t.string "unconfirmed_email" + t.string "unlock_token" + t.datetime "updated_at", null: false + t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true + t.index ["email"], name: "index_users_on_email", unique: true + t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true + t.index ["unlock_token"], name: "index_users_on_unlock_token", unique: true + end + + add_foreign_key "medications", "medication_types" + add_foreign_key "people", "relationships" end diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..2f58cce --- /dev/null +++ b/mise.toml @@ -0,0 +1,3 @@ +[tools] +node = "latest" +ruby = "4.0.5" diff --git a/test/controllers/home_controller_test.rb b/test/controllers/home_controller_test.rb new file mode 100644 index 0000000..eac0e33 --- /dev/null +++ b/test/controllers/home_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class HomeControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/controllers/medication_types_controller_test.rb b/test/controllers/medication_types_controller_test.rb new file mode 100644 index 0000000..684c1a4 --- /dev/null +++ b/test/controllers/medication_types_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class MedicationTypesControllerTest < ActionDispatch::IntegrationTest + setup do + @medication_type = medication_types(:one) + end + + test "should get index" do + get medication_types_url + assert_response :success + end + + test "should get new" do + get new_medication_type_url + assert_response :success + end + + test "should create medication_type" do + assert_difference("MedicationType.count") do + post medication_types_url, params: { medication_type: { name: @medication_type.name } } + end + + assert_redirected_to medication_type_url(MedicationType.last) + end + + test "should show medication_type" do + get medication_type_url(@medication_type) + assert_response :success + end + + test "should get edit" do + get edit_medication_type_url(@medication_type) + assert_response :success + end + + test "should update medication_type" do + patch medication_type_url(@medication_type), params: { medication_type: { name: @medication_type.name } } + assert_redirected_to medication_type_url(@medication_type) + end + + test "should destroy medication_type" do + assert_difference("MedicationType.count", -1) do + delete medication_type_url(@medication_type) + end + + assert_redirected_to medication_types_url + end +end diff --git a/test/controllers/medications_controller_test.rb b/test/controllers/medications_controller_test.rb new file mode 100644 index 0000000..58f7f29 --- /dev/null +++ b/test/controllers/medications_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class MedicationsControllerTest < ActionDispatch::IntegrationTest + setup do + @medication = medications(:one) + end + + test "should get index" do + get medications_url + assert_response :success + end + + test "should get new" do + get new_medication_url + assert_response :success + end + + test "should create medication" do + assert_difference("Medication.count") do + post medications_url, params: { medication: { current: @medication.current, dosage: @medication.dosage, form: @medication.form, frequency: @medication.frequency, medication_type_id: @medication.medication_type_id, name: @medication.name, notes: @medication.notes, purpose: @medication.purpose, refill: @medication.refill, start_date: @medication.start_date, stop_date: @medication.stop_date, time_of_day: @medication.time_of_day } } + end + + assert_redirected_to medication_url(Medication.last) + end + + test "should show medication" do + get medication_url(@medication) + assert_response :success + end + + test "should get edit" do + get edit_medication_url(@medication) + assert_response :success + end + + test "should update medication" do + patch medication_url(@medication), params: { medication: { current: @medication.current, dosage: @medication.dosage, form: @medication.form, frequency: @medication.frequency, medication_type_id: @medication.medication_type_id, name: @medication.name, notes: @medication.notes, purpose: @medication.purpose, refill: @medication.refill, start_date: @medication.start_date, stop_date: @medication.stop_date, time_of_day: @medication.time_of_day } } + assert_redirected_to medication_url(@medication) + end + + test "should destroy medication" do + assert_difference("Medication.count", -1) do + delete medication_url(@medication) + end + + assert_redirected_to medications_url + end +end diff --git a/test/controllers/people_controller_test.rb b/test/controllers/people_controller_test.rb new file mode 100644 index 0000000..3dfc530 --- /dev/null +++ b/test/controllers/people_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class PeopleControllerTest < ActionDispatch::IntegrationTest + setup do + @person = people(:one) + end + + test "should get index" do + get people_url + assert_response :success + end + + test "should get new" do + get new_person_url + assert_response :success + end + + test "should create person" do + assert_difference("Person.count") do + post people_url, params: { person: { date_of_birth: @person.date_of_birth, email: @person.email, first_name: @person.first_name, last_name: @person.last_name, relationship_id: @person.relationship_id, social_security_number: @person.social_security_number } } + end + + assert_redirected_to person_url(Person.last) + end + + test "should show person" do + get person_url(@person) + assert_response :success + end + + test "should get edit" do + get edit_person_url(@person) + assert_response :success + end + + test "should update person" do + patch person_url(@person), params: { person: { date_of_birth: @person.date_of_birth, email: @person.email, first_name: @person.first_name, last_name: @person.last_name, relationship_id: @person.relationship_id, social_security_number: @person.social_security_number } } + assert_redirected_to person_url(@person) + end + + test "should destroy person" do + assert_difference("Person.count", -1) do + delete person_url(@person) + end + + assert_redirected_to people_url + end +end diff --git a/test/fixtures/medication_types.yml b/test/fixtures/medication_types.yml new file mode 100644 index 0000000..7d41224 --- /dev/null +++ b/test/fixtures/medication_types.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/test/fixtures/medications.yml b/test/fixtures/medications.yml new file mode 100644 index 0000000..2487777 --- /dev/null +++ b/test/fixtures/medications.yml @@ -0,0 +1,29 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + medication_type: two + current: false + dosage: MyString + frequency: MyString + time_of_day: MyString + form: MyString + purpose: MyText + start_date: 2026-08-29 + stop_date: 2026-08-29 + refill: MyString + notes: MyText + +two: + name: MyString + medication_type: two + current: false + dosage: MyString + frequency: MyString + time_of_day: MyString + form: MyString + purpose: MyText + start_date: 2026-08-29 + stop_date: 2026-08-29 + refill: MyString + notes: MyText diff --git a/test/fixtures/people.yml b/test/fixtures/people.yml new file mode 100644 index 0000000..a6957bc --- /dev/null +++ b/test/fixtures/people.yml @@ -0,0 +1,17 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + first_name: MyString + last_name: MyString + date_of_birth: 2026-08-28 + social_security_number: MyString + email: MyString + relationship: one + +two: + first_name: MyString + last_name: MyString + date_of_birth: 2026-08-28 + social_security_number: MyString + email: MyString + relationship: two diff --git a/test/fixtures/relationships.yml b/test/fixtures/relationships.yml new file mode 100644 index 0000000..7d41224 --- /dev/null +++ b/test/fixtures/relationships.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/test/models/medication_test.rb b/test/models/medication_test.rb new file mode 100644 index 0000000..8fcd105 --- /dev/null +++ b/test/models/medication_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class MedicationTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/medication_type_test.rb b/test/models/medication_type_test.rb new file mode 100644 index 0000000..6417e1a --- /dev/null +++ b/test/models/medication_type_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class MedicationTypeTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/person_test.rb b/test/models/person_test.rb new file mode 100644 index 0000000..357c9af --- /dev/null +++ b/test/models/person_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class PersonTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/relationship_test.rb b/test/models/relationship_test.rb new file mode 100644 index 0000000..6b1491a --- /dev/null +++ b/test/models/relationship_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class RelationshipTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/user_test.rb b/test/models/user_test.rb new file mode 100644 index 0000000..5c07f49 --- /dev/null +++ b/test/models/user_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class UserTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end