Skip to content

Commit

Permalink
1021 Refactor Pet instance method to use the Match model instead of t…
Browse files Browse the repository at this point in the history
…he AdopterApplication model (#1055)

* Refactor Pet#is_adopted? method to use Match model

* Improve performance of staff pets index page

* Remove 2 unneeded queries from rendering /staff/pets

* Fix N+1 in AdoptablePetsController

* Fix N+1 for pets in LikesController

* Fix AdoptablePetsController#index action to expose only unadopted pets
  • Loading branch information
coalest authored Oct 13, 2024
1 parent 6f55760 commit 389ed26
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 13 deletions.
5 changes: 2 additions & 3 deletions app/controllers/organizations/adoptable_pets_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ class Organizations::AdoptablePetsController < Organizations::BaseController
helper_method :get_animals

def index
@q = authorized_scope(Pet.includes(:adopter_applications, images_attachments: :blob),
with: Organizations::AdoptablePetPolicy).ransack(params[:q])
@q = authorized_scope(Pet.unadopted, with: Organizations::AdoptablePetPolicy).ransack(params[:q])
@pagy, paginated_adoptable_pets = pagy(
@q.result,
@q.result.includes(:adopter_applications, :matches, images_attachments: :blob),
limit: 9
)
@pets = paginated_adoptable_pets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def index

likes = current_user.person.likes
@likes_by_id = likes.index_by(&:pet_id)
@pets = current_user.person.liked_pets
@pets = current_user.person.liked_pets.includes(:matches, :adopter_applications, images_attachments: :blob)
end

def create
Expand Down
5 changes: 4 additions & 1 deletion app/controllers/organizations/staff/pets_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ def index
authorize! Pet, context: {organization: Current.organization}

@q = Pet.ransack(params[:q])
@pagy, @pets = pagy(authorized_scope(@q.result), limit: 10)
@pagy, @pets = pagy(
authorized_scope(@q.result.includes(:matches, :adopter_applications, images_attachments: :blob)),
limit: 10
)
end

def new
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/pet_ransackable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def ransackable_attributes(auth_object = nil)
end

def ransackable_associations(auth_object = nil)
["adopter_applications"]
["adopter_applications", "matches"]
end

def ransackable_scopes(auth_object = nil)
Expand Down
12 changes: 10 additions & 2 deletions app/models/pet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,19 @@ def has_adoption_pending?
end

def is_adopted?
adopter_applications.any? { |app| app.status == "adoption_made" }
if matches.loaded?
matches.any? { |m| m.match_type == "adoption" }
else
matches.adoption.any?
end
end

def in_foster?
matches.in_foster.exists?
if matches.loaded?
matches.any? { |m| m.match_type == "foster" && (m.start_date..m.end_date).cover?(Time.now.utc) }
else
matches.in_foster.any?
end
end

def open?
Expand Down
10 changes: 10 additions & 0 deletions test/controllers/organizations/adoptable_pets_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ class Organizations::AdoptablePetsControllerTest < ActionDispatch::IntegrationTe
get adoptable_pets_url
end
end

should "assign only unadopted pets" do
adopted_pet = create(:pet, :adopted)

get adoptable_pets_url

assert_response :success
assert_equal 1, assigns[:pets].count
assert assigns[:pets].pluck(:id).exclude?(adopted_pet.id)
end
end

context "#show" do
Expand Down
6 changes: 6 additions & 0 deletions test/factories/matches.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,11 @@
start_date { Faker::Time.between(from: 1.year.ago, to: 1.month.from_now) }
end_date { start_date + rand(3..6).months }
end

trait :adoption do
match_type { :adoption }
start_date { Faker::Time.between(from: 1.year.ago, to: 1.day.ago) }
end_date { 1.day.from_now }
end
end
end
20 changes: 15 additions & 5 deletions test/models/pet_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,27 @@ class PetTest < ActiveSupport::TestCase
end

context "#is_adopted?" do
should "return true if there is an adopter application with 'adoption_pending' status" do
pet = Pet.new
adopter_application = pet.adopter_applications.new
adopter_application.status = "adoption_made"
should "return true if there is a match with 'adoption' match_type" do
pet = create(:pet)
match = create(:match, :adoption, pet:)
assert pet.is_adopted?

adopter_application.status = "awaiting_review"
match.update(match_type: "foster")
assert_not pet.is_adopted?
end
end

context "#in_foster?" do
should "return true if there is a match with 'foster' match_type" do
pet = create(:pet)
match = create(:foster, pet:, start_date: 1.month.ago, end_date: 1.day.from_now)
assert pet.in_foster?

match.update(match_type: "adoption")
assert_not pet.in_foster?
end
end

context "ransack_adopted" do
setup do
create(:pet)
Expand Down

0 comments on commit 389ed26

Please sign in to comment.