From 07ff0f026c55981065bbed55674582cbbfd8570f Mon Sep 17 00:00:00 2001 From: Andrew Canfield Date: Sun, 9 Jun 2024 10:48:48 -0700 Subject: [PATCH 1/3] Added weight to pets --- app/controllers/pets_controller.rb | 2 +- app/views/pets/_form.html.erb | 5 +++++ app/views/pets/_pet.html.erb | 5 +++++ app/views/pets/_pet.json.jbuilder | 2 +- db/migrate/20240609173229_add_weight_to_pets.rb | 5 +++++ db/schema.rb | 3 ++- db/seeds.rb | 8 ++++---- test/controllers/pets_controller_test.rb | 4 ++-- test/fixtures/pets.yml | 14 ++++++++------ test/system/pets_test.rb | 2 ++ 10 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 db/migrate/20240609173229_add_weight_to_pets.rb diff --git a/app/controllers/pets_controller.rb b/app/controllers/pets_controller.rb index 8db2d0b..fc26672 100644 --- a/app/controllers/pets_controller.rb +++ b/app/controllers/pets_controller.rb @@ -65,6 +65,6 @@ def set_pet # Only allow a list of trusted parameters through. def pet_params - params.require(:pet).permit(:name, :kind, :breed) + params.require(:pet).permit(:name, :kind, :breed, :weight) end end diff --git a/app/views/pets/_form.html.erb b/app/views/pets/_form.html.erb index 51e9be1..ec9f2d4 100644 --- a/app/views/pets/_form.html.erb +++ b/app/views/pets/_form.html.erb @@ -26,6 +26,11 @@ <%= form.text_field :breed %> +
+ <%= form.label :weight, style: "display: block" %> + <%= form.number_field :weight %> +
+
<%= form.submit %>
diff --git a/app/views/pets/_pet.html.erb b/app/views/pets/_pet.html.erb index fcf029f..bcef191 100644 --- a/app/views/pets/_pet.html.erb +++ b/app/views/pets/_pet.html.erb @@ -14,4 +14,9 @@ <%= pet.breed %>

+

+ Weight: + <%= pet.weight %> +

+ diff --git a/app/views/pets/_pet.json.jbuilder b/app/views/pets/_pet.json.jbuilder index 772e3a2..e035ddc 100644 --- a/app/views/pets/_pet.json.jbuilder +++ b/app/views/pets/_pet.json.jbuilder @@ -1,2 +1,2 @@ -json.extract! pet, :id, :name, :kind, :breed, :created_at, :updated_at +json.extract! pet, :id, :name, :kind, :breed, :weight, :created_at, :updated_at json.url pet_url(pet, format: :json) diff --git a/db/migrate/20240609173229_add_weight_to_pets.rb b/db/migrate/20240609173229_add_weight_to_pets.rb new file mode 100644 index 0000000..f18b811 --- /dev/null +++ b/db/migrate/20240609173229_add_weight_to_pets.rb @@ -0,0 +1,5 @@ +class AddWeightToPets < ActiveRecord::Migration[7.1] + def change + add_column :pets, :weight, :decimal, precision: 5, scale: 2, default: nil + end +end diff --git a/db/schema.rb b/db/schema.rb index a65d797..4a93cf0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,13 +10,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_05_15_193131) do +ActiveRecord::Schema[7.1].define(version: 2024_06_09_173229) do create_table "pets", force: :cascade do |t| t.string "name" t.string "kind" t.string "breed" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.decimal "weight", precision: 5, scale: 2 end end diff --git a/db/seeds.rb b/db/seeds.rb index 857ab7b..8d66257 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -8,10 +8,10 @@ # Create pets Pet.create!( [ - { name: 'Buddy', kind: 'Dog', breed: 'Golden Retriever' }, - { name: 'Whiskers', kind: 'Cat', breed: 'Siamese' }, - { name: 'Tweety', kind: 'Bird', breed: 'Canary' }, - { name: 'Nemo', kind: 'Fish', breed: 'Clownfish' } + { name: 'Buddy', kind: 'Dog', breed: 'Golden Retriever', weight: 60 }, + { name: 'Whiskers', kind: 'Cat', breed: 'Siamese', weight: 8.5 }, + { name: 'Tweety', kind: 'Bird', breed: 'Canary', weight: 1 }, + { name: 'Nemo', kind: 'Fish', breed: 'Clownfish', weight: 0.25 } ] ) diff --git a/test/controllers/pets_controller_test.rb b/test/controllers/pets_controller_test.rb index b3a1db2..6e1b09c 100644 --- a/test/controllers/pets_controller_test.rb +++ b/test/controllers/pets_controller_test.rb @@ -17,7 +17,7 @@ class PetsControllerTest < ActionDispatch::IntegrationTest test "should create pet" do assert_difference("Pet.count") do - post pets_url, params: { pet: { breed: @pet.breed, kind: @pet.kind, name: @pet.name } } + post pets_url, params: { pet: { breed: @pet.breed, kind: @pet.kind, name: @pet.name, weight: @pet.weight } } end assert_redirected_to pet_url(Pet.last) @@ -34,7 +34,7 @@ class PetsControllerTest < ActionDispatch::IntegrationTest end test "should update pet" do - patch pet_url(@pet), params: { pet: { breed: @pet.breed, kind: @pet.kind, name: @pet.name } } + patch pet_url(@pet), params: { pet: { breed: @pet.breed, kind: @pet.kind, name: @pet.name, weight: @pet.weight } } assert_redirected_to pet_url(@pet) end diff --git a/test/fixtures/pets.yml b/test/fixtures/pets.yml index ed65b20..6884959 100644 --- a/test/fixtures/pets.yml +++ b/test/fixtures/pets.yml @@ -1,11 +1,13 @@ # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: - name: MyString - kind: MyString - breed: MyString + name: Fido + kind: Dog + breed: Labrador + weight: 65 two: - name: MyString - kind: MyString - breed: MyString + name: Figaro + kind: Cat + breed: Tabby + weight: 9.2 diff --git a/test/system/pets_test.rb b/test/system/pets_test.rb index 6805822..1de90b3 100644 --- a/test/system/pets_test.rb +++ b/test/system/pets_test.rb @@ -17,6 +17,7 @@ class PetsTest < ApplicationSystemTestCase fill_in "Breed", with: @pet.breed fill_in "Kind", with: @pet.kind fill_in "Name", with: @pet.name + fill_in "Weight", with: @pet.weight click_on "Create Pet" assert_text "Pet was successfully created" @@ -30,6 +31,7 @@ class PetsTest < ApplicationSystemTestCase fill_in "Breed", with: @pet.breed fill_in "Kind", with: @pet.kind fill_in "Name", with: @pet.name + fill_in "Weight", with: @pet.weight click_on "Update Pet" assert_text "Pet was successfully updated" From 4bb13016c566c1d3e43e34af334de1311fac5e24 Mon Sep 17 00:00:00 2001 From: Andrew Canfield Date: Tue, 11 Jun 2024 14:51:33 -0700 Subject: [PATCH 2/3] Added owner who can have many pets --- app/assets/stylesheets/application.css | 15 ++++ app/controllers/owners_controller.rb | 70 +++++++++++++++++++ app/controllers/pets_controller.rb | 2 +- app/models/owner.rb | 4 ++ app/models/pet.rb | 2 + app/views/layouts/application.html.erb | 11 +++ app/views/owners/_form.html.erb | 22 ++++++ app/views/owners/_owner.html.erb | 7 ++ app/views/owners/_owner.json.jbuilder | 2 + app/views/owners/edit.html.erb | 10 +++ app/views/owners/index.html.erb | 15 ++++ app/views/owners/index.json.jbuilder | 1 + app/views/owners/new.html.erb | 9 +++ app/views/owners/show.html.erb | 13 ++++ app/views/owners/show.json.jbuilder | 1 + app/views/pets/_form.html.erb | 5 ++ app/views/pets/_pet.html.erb | 2 +- app/views/pets/index.html.erb | 6 +- app/views/pets/show.html.erb | 6 ++ config/routes.rb | 2 + db/migrate/20240610023329_create_owners.rb | 9 +++ .../20240610023511_add_owner_to_pets.rb | 5 ++ db/schema.rb | 11 ++- db/seeds.rb | 26 ++++--- test/controllers/owners_controller_test.rb | 49 +++++++++++++ test/controllers/pets_controller_test.rb | 22 +++++- test/fixtures/owners.yml | 9 +++ test/fixtures/pets.yml | 2 + test/models/owner_test.rb | 7 ++ test/system/owners_test.rb | 41 +++++++++++ 30 files changed, 371 insertions(+), 15 deletions(-) create mode 100644 app/controllers/owners_controller.rb create mode 100644 app/models/owner.rb create mode 100644 app/views/owners/_form.html.erb create mode 100644 app/views/owners/_owner.html.erb create mode 100644 app/views/owners/_owner.json.jbuilder create mode 100644 app/views/owners/edit.html.erb create mode 100644 app/views/owners/index.html.erb create mode 100644 app/views/owners/index.json.jbuilder create mode 100644 app/views/owners/new.html.erb create mode 100644 app/views/owners/show.html.erb create mode 100644 app/views/owners/show.json.jbuilder create mode 100644 db/migrate/20240610023329_create_owners.rb create mode 100644 db/migrate/20240610023511_add_owner_to_pets.rb create mode 100644 test/controllers/owners_controller_test.rb create mode 100644 test/fixtures/owners.yml create mode 100644 test/models/owner_test.rb create mode 100644 test/system/owners_test.rb diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 288b9ab..f6b6c89 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -13,3 +13,18 @@ *= require_tree . *= require_self */ + +nav { + border-bottom: 1px solid #ffffff; +} + +nav ul { + margin: 0; + padding: 10px 0; +} + +nav ul li { + display: inline-block; + list-style-type: none; + padding-right: 20px; +} diff --git a/app/controllers/owners_controller.rb b/app/controllers/owners_controller.rb new file mode 100644 index 0000000..377c420 --- /dev/null +++ b/app/controllers/owners_controller.rb @@ -0,0 +1,70 @@ +class OwnersController < ApplicationController + before_action :set_owner, only: %i[ show edit update destroy ] + + # GET /owners or /owners.json + def index + @owners = Owner.all + end + + # GET /owners/1 or /owners/1.json + def show + end + + # GET /owners/new + def new + @owner = Owner.new + end + + # GET /owners/1/edit + def edit + end + + # POST /owners or /owners.json + def create + @owner = Owner.new(owner_params) + + respond_to do |format| + if @owner.save + format.html { redirect_to owner_url(@owner), notice: "Owner was successfully created." } + format.json { render :show, status: :created, location: @owner } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @owner.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /owners/1 or /owners/1.json + def update + respond_to do |format| + if @owner.update(owner_params) + format.html { redirect_to owner_url(@owner), notice: "Owner was successfully updated." } + format.json { render :show, status: :ok, location: @owner } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @owner.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /owners/1 or /owners/1.json + def destroy + @owner.destroy! + + respond_to do |format| + format.html { redirect_to owners_url, notice: "Owner was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_owner + @owner = Owner.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def owner_params + params.require(:owner).permit(:name) + end +end diff --git a/app/controllers/pets_controller.rb b/app/controllers/pets_controller.rb index fc26672..28b0b81 100644 --- a/app/controllers/pets_controller.rb +++ b/app/controllers/pets_controller.rb @@ -65,6 +65,6 @@ def set_pet # Only allow a list of trusted parameters through. def pet_params - params.require(:pet).permit(:name, :kind, :breed, :weight) + params.require(:pet).permit(:name, :kind, :breed, :weight, :owner_id) end end diff --git a/app/models/owner.rb b/app/models/owner.rb new file mode 100644 index 0000000..510c4d4 --- /dev/null +++ b/app/models/owner.rb @@ -0,0 +1,4 @@ +class Owner < ApplicationRecord + + has_many :pets, dependent: :destroy +end diff --git a/app/models/pet.rb b/app/models/pet.rb index d1efb8a..1eee4f2 100644 --- a/app/models/pet.rb +++ b/app/models/pet.rb @@ -1,2 +1,4 @@ class Pet < ApplicationRecord + + belongs_to :owner end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 1cd1804..817e15e 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -11,6 +11,17 @@ + + + +
<%= yield %> +
+ diff --git a/app/views/owners/_form.html.erb b/app/views/owners/_form.html.erb new file mode 100644 index 0000000..4aed9a3 --- /dev/null +++ b/app/views/owners/_form.html.erb @@ -0,0 +1,22 @@ +<%= form_with(model: owner) do |form| %> + <% if owner.errors.any? %> +
+

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

+ +
    + <% owner.errors.each do |error| %> +
  • <%= error.full_message %>
  • + <% end %> +
+
+ <% end %> + +
+ <%= form.label :name, style: "display: block" %> + <%= form.text_field :name %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/owners/_owner.html.erb b/app/views/owners/_owner.html.erb new file mode 100644 index 0000000..70091b5 --- /dev/null +++ b/app/views/owners/_owner.html.erb @@ -0,0 +1,7 @@ +
+

+ Owner: + <%= owner.name %> +

+ +
diff --git a/app/views/owners/_owner.json.jbuilder b/app/views/owners/_owner.json.jbuilder new file mode 100644 index 0000000..352112a --- /dev/null +++ b/app/views/owners/_owner.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! owner, :id, :name, :created_at, :updated_at +json.url owner_url(owner, format: :json) diff --git a/app/views/owners/edit.html.erb b/app/views/owners/edit.html.erb new file mode 100644 index 0000000..8c8661a --- /dev/null +++ b/app/views/owners/edit.html.erb @@ -0,0 +1,10 @@ +

Editing owner

+ +<%= render "form", owner: @owner %> + +
+ +
+ <%= link_to "Show this owner", @owner %> | + <%= link_to "Back to owners", owners_path %> +
diff --git a/app/views/owners/index.html.erb b/app/views/owners/index.html.erb new file mode 100644 index 0000000..b658d7a --- /dev/null +++ b/app/views/owners/index.html.erb @@ -0,0 +1,15 @@ +

<%= notice %>

+ +

Owners

+ +<%= link_to "New owner", new_owner_path %> + +
+ <% @owners.each do |owner| %> + <%= render owner %> +

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

+
+ <% end %> +
diff --git a/app/views/owners/index.json.jbuilder b/app/views/owners/index.json.jbuilder new file mode 100644 index 0000000..6b6949b --- /dev/null +++ b/app/views/owners/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @owners, partial: "owners/owner", as: :owner diff --git a/app/views/owners/new.html.erb b/app/views/owners/new.html.erb new file mode 100644 index 0000000..1824205 --- /dev/null +++ b/app/views/owners/new.html.erb @@ -0,0 +1,9 @@ +

New owner

+ +<%= render "form", owner: @owner %> + +
+ +
+ <%= link_to "Back to owners", owners_path %> +
diff --git a/app/views/owners/show.html.erb b/app/views/owners/show.html.erb new file mode 100644 index 0000000..1138eac --- /dev/null +++ b/app/views/owners/show.html.erb @@ -0,0 +1,13 @@ +

<%= notice %>

+ +<%= render @owner %> + +<%= render partial: "pets/pet", collection: @owner.pets %> + + +
+ <%= link_to "Edit this owner", edit_owner_path(@owner) %> | + <%= link_to "Back to owners", owners_path %> + + <%= button_to "Destroy this owner", @owner, method: :delete %> +
diff --git a/app/views/owners/show.json.jbuilder b/app/views/owners/show.json.jbuilder new file mode 100644 index 0000000..5c062c6 --- /dev/null +++ b/app/views/owners/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "owners/owner", owner: @owner diff --git a/app/views/pets/_form.html.erb b/app/views/pets/_form.html.erb index ec9f2d4..ccba635 100644 --- a/app/views/pets/_form.html.erb +++ b/app/views/pets/_form.html.erb @@ -11,6 +11,11 @@ <% end %> +
+ <%= form.label :owner, style: "display: block" %> + <%= form.collection_select :owner_id, Owner.all, :id, :name %> +
+
<%= form.label :name, style: "display: block" %> <%= form.text_field :name %> diff --git a/app/views/pets/_pet.html.erb b/app/views/pets/_pet.html.erb index bcef191..11a668d 100644 --- a/app/views/pets/_pet.html.erb +++ b/app/views/pets/_pet.html.erb @@ -1,7 +1,7 @@

Name: - <%= pet.name %> + <%= link_to pet.name, pet %>

diff --git a/app/views/pets/index.html.erb b/app/views/pets/index.html.erb index 1617972..9b334e8 100644 --- a/app/views/pets/index.html.erb +++ b/app/views/pets/index.html.erb @@ -2,13 +2,15 @@

Pets

+<%= link_to "New pet", new_pet_path %> +
<% @pets.each do |pet| %> <%= render pet %>

<%= link_to "Show this pet", pet %>

+ +
<% end %>
- -<%= link_to "New pet", new_pet_path %> diff --git a/app/views/pets/show.html.erb b/app/views/pets/show.html.erb index 4ebc28b..3a5e3fa 100644 --- a/app/views/pets/show.html.erb +++ b/app/views/pets/show.html.erb @@ -1,7 +1,13 @@

<%= notice %>

+ <%= render @pet %> +

+ Owner: + <%= link_to @pet.owner.name, @pet.owner %> +

+
<%= link_to "Edit this pet", edit_pet_path(@pet) %> | <%= link_to "Back to pets", pets_path %> diff --git a/config/routes.rb b/config/routes.rb index ae33912..5d64be7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :owners resources :pets # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html @@ -8,4 +9,5 @@ # Defines the root path route ("/") # root "posts#index" + root "owners#index" end diff --git a/db/migrate/20240610023329_create_owners.rb b/db/migrate/20240610023329_create_owners.rb new file mode 100644 index 0000000..c0e427c --- /dev/null +++ b/db/migrate/20240610023329_create_owners.rb @@ -0,0 +1,9 @@ +class CreateOwners < ActiveRecord::Migration[7.1] + def change + create_table :owners do |t| + t.string :name + + t.timestamps + end + end +end diff --git a/db/migrate/20240610023511_add_owner_to_pets.rb b/db/migrate/20240610023511_add_owner_to_pets.rb new file mode 100644 index 0000000..51aa3e0 --- /dev/null +++ b/db/migrate/20240610023511_add_owner_to_pets.rb @@ -0,0 +1,5 @@ +class AddOwnerToPets < ActiveRecord::Migration[7.1] + def change + add_reference :pets, :owner, null: false, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 4a93cf0..b07db2b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,13 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_06_09_173229) do +ActiveRecord::Schema[7.1].define(version: 2024_06_10_023511) do + create_table "owners", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "pets", force: :cascade do |t| t.string "name" t.string "kind" @@ -18,6 +24,9 @@ t.datetime "created_at", null: false t.datetime "updated_at", null: false t.decimal "weight", precision: 5, scale: 2 + t.integer "owner_id", null: false + t.index ["owner_id"], name: "index_pets_on_owner_id" end + add_foreign_key "pets", "owners" end diff --git a/db/seeds.rb b/db/seeds.rb index 8d66257..0bda706 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -3,16 +3,26 @@ # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). # # Clear existing data + Pet.destroy_all +Owner.destroy_all + +Owner.create([ + {name: "Arbuckle"}, + {name: "Granny"} +]) + +puts "Created #{Owner.count} Owners" # Create pets -Pet.create!( - [ - { name: 'Buddy', kind: 'Dog', breed: 'Golden Retriever', weight: 60 }, - { name: 'Whiskers', kind: 'Cat', breed: 'Siamese', weight: 8.5 }, - { name: 'Tweety', kind: 'Bird', breed: 'Canary', weight: 1 }, - { name: 'Nemo', kind: 'Fish', breed: 'Clownfish', weight: 0.25 } - ] -) +Owner.find_by(name: 'Arbuckle').pets.create!([ + { name: 'Buddy', kind: 'Dog', breed: 'Golden Retriever', weight: 60 }, + { name: 'Whiskers', kind: 'Cat', breed: 'Siamese', weight: 8.5 }, +]) + +Owner.find_by(name: 'Granny').pets.create!([ + { name: 'Tweety', kind: 'Bird', breed: 'Canary', weight: 1 }, + { name: 'Nemo', kind: 'Fish', breed: 'Clownfish', weight: 0.25} +]) puts "Created #{Pet.count} pets" diff --git a/test/controllers/owners_controller_test.rb b/test/controllers/owners_controller_test.rb new file mode 100644 index 0000000..b5a29c9 --- /dev/null +++ b/test/controllers/owners_controller_test.rb @@ -0,0 +1,49 @@ +require "test_helper" + +class OwnersControllerTest < ActionDispatch::IntegrationTest + setup do + @owner = owners(:one) + end + + test "should get index" do + get owners_url + assert_response :success + end + + test "should get new" do + get new_owner_url + assert_response :success + end + + test "should create owner" do + assert_difference("Owner.count") do + post owners_url, params: { owner: { name: @owner.name } } + end + + assert_redirected_to owner_url(Owner.last) + end + + test "should show owner" do + get owner_url(@owner) + assert_response :success + end + + test "should get edit" do + get edit_owner_url(@owner) + assert_response :success + end + + test "should update owner" do + patch owner_url(@owner), params: { owner: { name: @owner.name } } + assert_redirected_to owner_url(@owner) + end + + test "should destroy owner" do + assert_difference("Owner.count", -1) do + delete owner_url(@owner) + end + + assert_redirected_to owners_url + end + +end diff --git a/test/controllers/pets_controller_test.rb b/test/controllers/pets_controller_test.rb index 6e1b09c..dc4d377 100644 --- a/test/controllers/pets_controller_test.rb +++ b/test/controllers/pets_controller_test.rb @@ -16,8 +16,17 @@ class PetsControllerTest < ActionDispatch::IntegrationTest end test "should create pet" do + pet_params = { + pet: { + breed: @pet.breed, + kind: @pet.kind, + name: @pet.name, + weight: @pet.weight, + owner_id: @pet.owner.id + }} + assert_difference("Pet.count") do - post pets_url, params: { pet: { breed: @pet.breed, kind: @pet.kind, name: @pet.name, weight: @pet.weight } } + post pets_url, params: pet_params end assert_redirected_to pet_url(Pet.last) @@ -34,7 +43,16 @@ class PetsControllerTest < ActionDispatch::IntegrationTest end test "should update pet" do - patch pet_url(@pet), params: { pet: { breed: @pet.breed, kind: @pet.kind, name: @pet.name, weight: @pet.weight } } + pet_params = { + pet: { + breed: @pet.breed, + kind: @pet.kind, + name: @pet.name, + weight: @pet.weight, + owner_id: @pet.owner.id + }} + + patch pet_url(@pet), params: pet_params assert_redirected_to pet_url(@pet) end diff --git a/test/fixtures/owners.yml b/test/fixtures/owners.yml new file mode 100644 index 0000000..549306d --- /dev/null +++ b/test/fixtures/owners.yml @@ -0,0 +1,9 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + id: 1 + name: John + +two: + id: 2 + name: Lisa diff --git a/test/fixtures/pets.yml b/test/fixtures/pets.yml index 6884959..6387823 100644 --- a/test/fixtures/pets.yml +++ b/test/fixtures/pets.yml @@ -5,9 +5,11 @@ one: kind: Dog breed: Labrador weight: 65 + owner_id: 1 two: name: Figaro kind: Cat breed: Tabby weight: 9.2 + owner_id: 2 diff --git a/test/models/owner_test.rb b/test/models/owner_test.rb new file mode 100644 index 0000000..e7d98c3 --- /dev/null +++ b/test/models/owner_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class OwnerTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/system/owners_test.rb b/test/system/owners_test.rb new file mode 100644 index 0000000..d278ffb --- /dev/null +++ b/test/system/owners_test.rb @@ -0,0 +1,41 @@ +require "application_system_test_case" + +class OwnersTest < ApplicationSystemTestCase + setup do + @owner = owners(:one) + end + + test "visiting the index" do + visit owners_url + assert_selector "h1", text: "Owners" + end + + test "should create owner" do + visit owners_url + click_on "New owner" + + fill_in "Name", with: @owner.name + click_on "Create Owner" + + assert_text "Owner was successfully created" + click_on "Back" + end + + test "should update Owner" do + visit owner_url(@owner) + click_on "Edit this owner", match: :first + + fill_in "Name", with: @owner.name + click_on "Update Owner" + + assert_text "Owner was successfully updated" + click_on "Back" + end + + test "should destroy Owner" do + visit owner_url(@owner) + click_on "Destroy this owner", match: :first + + assert_text "Owner was successfully destroyed" + end +end From 3f6a346037e656175aaa07eedfd3d99b04c4975e Mon Sep 17 00:00:00 2001 From: Andrew Canfield Date: Wed, 12 Jun 2024 10:17:23 -0700 Subject: [PATCH 3/3] Added DogAPI functionality including rake task to load name to id translation --- app/controllers/breeds_controller.rb | 8 ++++++++ app/models/breed.rb | 3 +++ app/services/dog_api_service.rb | 17 +++++++++++++++ app/views/breeds/show.html.erb | 13 ++++++++++++ app/views/pets/_pet.html.erb | 2 +- config/routes.rb | 1 + db/migrate/20240612143827_create_breeds.rb | 12 +++++++++++ db/schema.rb | 9 +++++++- lib/tasks/breeds.rake | 24 ++++++++++++++++++++++ test/controllers/breeds_controller_test.rb | 12 +++++++++++ 10 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 app/controllers/breeds_controller.rb create mode 100644 app/models/breed.rb create mode 100644 app/services/dog_api_service.rb create mode 100644 app/views/breeds/show.html.erb create mode 100644 db/migrate/20240612143827_create_breeds.rb create mode 100644 lib/tasks/breeds.rake create mode 100644 test/controllers/breeds_controller_test.rb diff --git a/app/controllers/breeds_controller.rb b/app/controllers/breeds_controller.rb new file mode 100644 index 0000000..7753334 --- /dev/null +++ b/app/controllers/breeds_controller.rb @@ -0,0 +1,8 @@ + + +class BreedsController < ApplicationController + def show + id = Breed.find_by(name: params[:name]).id + @data = DogApiService.get_breed(id)['data'] + end +end diff --git a/app/models/breed.rb b/app/models/breed.rb new file mode 100644 index 0000000..ee48016 --- /dev/null +++ b/app/models/breed.rb @@ -0,0 +1,3 @@ +class Breed < ApplicationRecord + +end diff --git a/app/services/dog_api_service.rb b/app/services/dog_api_service.rb new file mode 100644 index 0000000..5d176ca --- /dev/null +++ b/app/services/dog_api_service.rb @@ -0,0 +1,17 @@ +require 'net/http' + +class DogApiService + + def self.list_breeds(page=1) + uri = URI("https://dogapi.dog/api/v2/breeds?page[number]=#{page}") + response = Net::HTTP.get_response(uri) + JSON.parse(response.body) + end + + def self.get_breed(id) + uri = URI.parse("https://dogapi.dog/api/v2/breeds/#{id}") + response = Net::HTTP.get_response(uri) + JSON.parse(response.body) + end + +end diff --git a/app/views/breeds/show.html.erb b/app/views/breeds/show.html.erb new file mode 100644 index 0000000..62473b5 --- /dev/null +++ b/app/views/breeds/show.html.erb @@ -0,0 +1,13 @@ +

Breed Details

+ +

+ id: <%= @data['id'] %> +

+ +

+ name: <%= @data['attributes']['name'] %> +

+ +

+ description: <%= @data['attributes']['description'] %> +

diff --git a/app/views/pets/_pet.html.erb b/app/views/pets/_pet.html.erb index 11a668d..8574394 100644 --- a/app/views/pets/_pet.html.erb +++ b/app/views/pets/_pet.html.erb @@ -11,7 +11,7 @@

Breed: - <%= pet.breed %> + <%= link_to pet.breed, breeds_show_path(name: pet.breed) %>

diff --git a/config/routes.rb b/config/routes.rb index 5d64be7..d29b75f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + get 'breeds/show' resources :owners resources :pets # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html diff --git a/db/migrate/20240612143827_create_breeds.rb b/db/migrate/20240612143827_create_breeds.rb new file mode 100644 index 0000000..847d194 --- /dev/null +++ b/db/migrate/20240612143827_create_breeds.rb @@ -0,0 +1,12 @@ +class CreateBreeds < ActiveRecord::Migration[7.1] + def change + #sqllite does not support the uuid datatype + create_table :breeds, id: :string do |t| + t.string :name + + t.timestamps + end + + add_index :breeds, :name, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index b07db2b..976fbc7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_06_10_023511) do +ActiveRecord::Schema[7.1].define(version: 2024_06_12_143827) do + create_table "breeds", id: :string, force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_breeds_on_name", unique: true + end + create_table "owners", force: :cascade do |t| t.string "name" t.datetime "created_at", null: false diff --git a/lib/tasks/breeds.rake b/lib/tasks/breeds.rake new file mode 100644 index 0000000..7dff7b9 --- /dev/null +++ b/lib/tasks/breeds.rake @@ -0,0 +1,24 @@ + + +desc "Load breeds id and name from DogAPI to database" +task load_breeds: [:environment] do + puts "Removing all breeds from database" + Breed.delete_all + + puts "Loading breeds from DogAPI" + page = 1 + while true do + print "." + response = DogApiService.list_breeds(page) + response['data'].each do |breed| + Breed.create( + id: breed['id'], + name: breed['attributes']['name'] + ) + end + break if response['links']['next'].nil? + page += 1 + end + + puts "\n#{Breed.all.count} Breeds loaded" +end diff --git a/test/controllers/breeds_controller_test.rb b/test/controllers/breeds_controller_test.rb new file mode 100644 index 0000000..05a79c1 --- /dev/null +++ b/test/controllers/breeds_controller_test.rb @@ -0,0 +1,12 @@ +require "test_helper" + +class BreedsControllerTest < ActionDispatch::IntegrationTest + setup do + Breed.create(id: "fee91641-2a2e-4c4f-b557-cff67c5803bc", name: "Golden Retriever") + end + + test "should get show" do + get breeds_show_url(name: "Golden Retriever") + assert_response :success + end +end