Since this is a case where you have a "has and belongs to many" relationship but you want to store extra information about the relationship itself (the fact that an image is "featured" for a post), I would try a has_many :through
arrangement instead. Something like this:
class Post < ActiveRecord::Base
has_many :post_images, inverse_of: :post
has_many :images, through: :post_images
has_one :featured_post_image, class_name: PostImage,
inverse_of: :post, conditions: { is_featured: true }
has_one :featured_image, through: :featured_post_image
accepts_nested_attributes_for :post_images, allow_destroy: true
attr_accessible :post_images_attributes
end
class PostImage < ActiveRecord::Base
belongs_to :post
belongs_to :image
attr_accessible :image_id
end
class Image < ActiveRecord::Base
has_many :post_images
has_many :posts, through: :post_images
end
Unfortunately, adding validations to ensure that a post can never have more than one featured image is trickier than it looks. You can put a validation on Post
, but that won't save you if some other part of your app creates PostImages directly without touching their associated posts. If anyone else reading this has some insight into this problem, I'd love to hear it.