Home > Net >  Finding a record with has many relationship and other params Ruby on Rails MySQL
Finding a record with has many relationship and other params Ruby on Rails MySQL

Time:06-10

I have two tables, pets and owners

class Owner < ApiModel

has_and_belongs_to_many :pets

and

class Pets < ApiModel

has_and_belongs_to_many :owners

So the example is three Owners, Frank, Mary, Hillary, who live together and own three pets (doggy, kitty, and fishy)

Owner1 = {name: "Mary", gender: "female", hair_color: "blue", pets: [pet1, pet2, pet3]} 
Owner2 = {name: "Hilary", gender: "female", hair_color: "green", pets: [pet1, pet2]} 
Owner3 = {name: "Frank", gender: "male", hair_color: "red", pets: [pet3]}
pet1 = {name: "doggy", gender: "female", animal: "dog"}
pet2 = {name: "kitty", gender: "male", animal: "cat"}
pet3 = {name: "fishy", gender: "male", animal: "fish"}

My goal is to return Owner 1 given that I know she owns pet3 and that she is female. I thought I could do something like this:

found_pet = Pet.find_by(animal: "fish") # will correctly only return the pet3 record
owner = Owner.where(hair_color: "blue").includes(pet: found_pet)

But I keep getting an error (Object doesn't support #inspect) when trying to find owner.

Is this maybe possible with using .join ?

Rails version 6.0.4.7

Ruby version ruby 3.1.1p18

UPDATE

Christos-Angelos Vasilopoulos had a good response for my original question but I had a follow up.

So what if I want to find where the owner own two pets:

found_pet1 = Pet.find_by(animal: "dog")
found_pet2 = Pet.find_by(animal: "cat") 
owner = Owner.where(hair_color: "blue").includes(pet: found_pet1).includes(pet: found_pet2)

CodePudding user response:

The best approach would be to use the association. Executing pet_record.owners returns all the pet owners. Then you need a query to return the right results.

Use find_by to get the first matching record for your query

found_pet.owners.find_by(hair_color: "blue")

Use where to get all the matching records for your query

found_pet.owners.where(hair_color: "blue")

PS: In your question your state that you need to return Owner1 as it is female, then I would suggest doing the following.

found_pet.owners.find_by(gender: "female")
found_pet.owners.where(gender: "female")
  • Related