简体   繁体   中英

rails relationships, 3 levels at least

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 don t know how to dig even deeper to reach the photos model. And anywhay i can model. And anywhay i can :include => :albums because i have no direct relations between place and 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.

There is a hash syntax for nested includes. It also works for joins.

@place = Place.find( params[:id], :include => {:albums => :photos} )

Here is the documentation for this http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html Look under the heading "Eager loading of associations"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM