Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: If Foo has_many :bars, do all :bars need to belong_to a Foo?

I'm working on an app that has a lot of photos in it, which are contributed by users. The photo-sharing aspect is the primary purpose of the app.

Sometimes it's helpful to create featured "Collections" of photos. So, this is easy enough in ActiveRecord: Collection has_many :photos and Photo belongs_to :collection.

The question I have is, for an 'ordinary' photo that doesn't belong to a special collection, should I:

A. Not have it belong to any collection at all. ie: photo.collection == nil

-or-

B. Create a generic "Community Collection" that holds every photo. ie by default photo.collection == 'Community'

I am also considering whether this should be a HABTM relationship.

Feedback would be much appreciated!

like image 727
Andrew Avatar asked Jan 20 '23 10:01

Andrew


1 Answers

It depends on what you're going to do with your uncollected photos, really. If you want the ability to show the uncollected photos with the same action you use to show a collection, then you'll want to have that generic collection. Otherwise, I'd leave it nil; I don't like mixing "seed" data with user data in the same table (which you'd be doing with the "uncollected" collection) - it's too easy to accidentally wipe out your user data when reseeding.

Should it be a HABTM relationship? Again, depends on how you want to use it. If there's a good chance you'll want photos to belong to multiple collections, go for it.

And the things that I've seen mentioned here that I would not do: Adding a 'ptype' attribute to tell singletons from collected photos (waste of DB space - you can already get that info by calling photo.collection_id.nil?); and using polymorphic models (you don't want singleton photos to behave drastically different, I assume, so this is added complexity for little to no benefit).

Named scopes, though, are a great idea, and will be particularly useful if you don't have the "uncollected" collection to find your singletons by:

#Apologies for the Rails 2.3 code - it's what I know...
named_scope :singletons, {:conditions => {:collection_id => nil}}

Or the HABTM version:

named_scope :singletons, lambda {
    {:conditions => ['NOT EXISTS (SELECT * FROM collections_photos WHERE photo_id = ?)', self.id]}
}

Hope this helps!

like image 189
Xavier Holt Avatar answered Jan 29 '23 09:01

Xavier Holt