Reputation:
So in my application I have the models People and Outfits. In my show controller for people, I get the list like this:
@people = Person.where("description LIKE ?", "%#{params[:description]}%")
And in my view I show the outfits of each person like this:
<% @people.each do |person| %>
<p> Name: <%= person.name %> </p>
<% @outfits = person.outfits %>
<% @outfits.each do |outfit|
<p> Name: <%= outfit.name %> </p>
<p> Description: <%= outfit.description %> </p>
<% end %>
<% end %>
But loading the outfits for each person, as I load many people on the page, takes too long. Is there some way I can inherit the outfits of each person so I don't have to wait so long for the page to load? Or is the only way to speed this up to make an index between outfits and people? Thanks for any help
Upvotes: 0
Views: 84
Reputation: 59
You can use .joins
or .includes
If you have a table full of Person and you use a :joins => outfits to pull in all the outfit information for sorting purposes, etc it will work fine and take less time than :include, but say you want to display the Person along with the outfit name, description, etc. To get the information using :joins, it will have to make separate SQL queries for each user it fetches, whereas if you used :include this information is ready for use.
Solution
Person.includes(:outfits).where("description LIKE ?", "%#{params[:description]}%")
Upvotes: 0
Reputation: 102222
Use a join to load the associated records:
@people = Person.eager_load(:outfits)
.where("description LIKE ?", "%#{params[:description]}%")
.limit(20) # optional
Otherwise you have what is called a N+1 query issue where each iteration through @people
will cause a separate database query to fetch outfits.
And yes the outfits.person_id
or whatever column that creates the association should have a foreign key index. Using the belongs_to
or references
macro in the migration will do this by default:
create_table :outfits do |t|
t.belongs_to :person, foreign_key: true
end
Upvotes: 2
Reputation: 404
you should set a limit like this:
@people = Person.where("description LIKE ?", "%#{params[:description]}%").limit(20)
change the number according to your preference.
Upvotes: 0