How can i authentically use rails relationships in my case?
I'm making a nightlife website, just for you to know the context. It has three models, i want to join on one page: Places, Albums, Photos.
So, photos
in albums
work great, i use there a custom-coded sql with joins.
But when i click on a place
i want to see info from place
model and a list of albums
with a sample photo
(first for example)
Now i have the following:
class Place < ActiveRecord::Base
has_many :albums
end
class Album < ActiveRecord::Base
has_many :photos
has_one :place
end
class Photo < ActiveRecord::Base
belongs_to :album
end
And there how i get it in my controller:
@place = Place.find( params[:id], :include => :albums )
and i get @place.albums as an object with albums data. But i dont know how to dig even deeper to reach the
photosmodel. And anywhay i can
:include => :albumsbecause i have no direct relations between
placeand
album, but i have them in
album > photo` so sql join is needed?
That's a complicated question, but i just don`t get it fully.
Thank you for any help, maybe a good link to read!
First of all, the association between Place and Album isn't correct. The way you have it setup, it looks like neither would have a foreign_key. In other words, it should be Album belongs_to :place
, with place_id
in the albums
table.
Second of all, to get the first photo for each album:
<% @place.albums.each do |album| %>
Sample Photo: <%= image_tag(album.photos.first.url) %>
<% end %>
If you really wanted to, you could get the first photo from the first album of a place in one line:
<%= image_tag(@place.albums.first.photos.first.url) %>
First note that this is prone to nil errors if you don't add in conditionals, so I don't actually recommend this method. But, if you were to use it, I would just add a method to the Place model:
def first_photo
albums.first.photos.first
end
And in your view:
<%= image_tag(@place.first_photo.url) %>
You'll want to join this stuff together as well so you're not performing too many queries. Wizard of Ogz answer covers that.