1
votes

Let's say you have two models Venue and Photo. Each Venue can have many Photos, but it can only have one FeaturedPhoto. Each Photo can be belong to many Venues and can be the FeaturedPhoto of more than one Venue too.

I already have the general has_and_belongs_to_many relationship set up and working through a join table with these models:

class Photo < ActiveRecord::Base
  mount_uploader :image, PhotoUploader
  has_and_belongs_to_many :venues
end

class Venue < ActiveRecord::Base
  has_and_belongs_to_many :photos
end

To add the FeaturedPhoto, it seems like I would need to add a column called featured_photo_id to the Venue model and then set up a has_many, belongs_to association between the two. But I'm not sure where to add the foreign_key info. Is this right?

class Photo < ActiveRecord::Base
  mount_uploader :image, PhotoUploader
  has_and_belongs_to_many :venues
  has_many :venues
end

class Venue < ActiveRecord::Base
  has_and_belongs_to_many :photos
  belongs_to :photo, foreign_key: "featured_photo_id", class_name: "Photo"
end

Or do I have to add foreign_key info to both models?

2

2 Answers

1
votes

This can be achieved if you add a model for intermediate table PhotosVenue and add a boolean column is_featured in this intermediate table.

I created a demo app to do exactly what you want. Check this github repo

Hope this helps :)

0
votes

has_many :through

I concur with SiriusROR - you need to use a has_many :through model, with an extra boolean attribute called featured:

#app/models/photo.rb
Class Photo < ActiveRecord::Base
   has_many :photo_venues
   has_many :venues, through: :venue_photos
end

#app/models/venue.rb
Class Venue < ActiveRecord::Base
   has_many :photo_venues
   has_many :photos, through: :venue_photos do
       def featured
           find_by featured: true
       end
   end
end

#app/models/photo_venue.rb
Class VenuePhoto < ActiveRecord::Base
   belongs_to :photo
   belongs_to :venue
end

--

Your schema for the :through model should be set up like this:

#photo_venues
id | photo_id | venue_id | featured | created_at | updated_at

--

This will allow you to call:

@venue.photos.featured # -> should bring back the single ActiveRecord object for the first featured photo in the collection