Reputation: 3574
Here's the setup, I have 3 classes: posts, users, and images. Users have posts and users have images. Posts have images as well, but only images that belong to their users as well. Multiple posts can have the same image, and multiple images can belong to one post. A post can have no images, and images don't necessarily need to belong to a post. With all this in mind, this is what I came up with for a database structure:
User.rb:
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
has_many :images, dependent: :destroy
end
Post.rb:
class Post < ActiveRecord::Base
has_and_belongs_to_many :images
belongs_to :user
end
Image.rb
class Image < ActiveRecord::Base
has_and_belongs_to_many :posts
belongs_to :user
end
Now, my problem is that I would like Posts to each have one featured image and Users to have profile image from their respective groups of images. My first instinct is to add the following to User.rb and Post.rb:
has_one :featured_image, class_name: "Image"
and this to Image.rb
belongs_to :post
belongs_to :user
But this doesn't seem right from a database perspective. First off, the second belong_to will be redundant on the image object, but further it seems wasteful. This would add two whole, mostly unused columns to the image table, and I don't like the idea of that seeing as I pay for my hosting space.
The next logical solution seems to be to reverse the has_one and belongs_to, putting the belongs_to on user and post and has_ones on image, but that doesn't seem very semantic. Further, it still seems redundant, as the many-to-many relationship already exists.
Is there a way to modify the images_posts table to represent these special associations from within the many-to-many relationship or would that be problematic to rails? Is there a better way of doing this that I'm not aware of or should I just revert to the reversed has_one's?
Upvotes: 0
Views: 256
Reputation: 1330
a typical solution for this is to store the image-type within the assocciation-table and having an extra assocciation-object:
Post.rb
class Post < ActiveRecord::Base
has_and_belongs_to_many :postImage
end
Image.rb
class Image < ActiveRecord::Base
has_and_belongs_to_many :postImage
end
PostImage.rb
class PostImage < ActiveRecord::Base
has_one :post
has_one :image
end
this will increase lines of code to get the assocciated object (post -> postImage -> image, instead of: post -> image), but keeps it easy to maintain and understand.
this really comes in handy when you have more additional information in the link than only the type...
Upvotes: 1