I’ve got a Product model, a Statuses model and a Productstatuses model.
Product has_many :productstatuses, :dependent => :destroy
Product has_many :statuses, :through => :productstatuses
Status has_many :productstatuses
Status has_many :products, :through => :productstatuses
Productstatus belongs_to :product
Productstatus belongs_to :status
I’m using the statuses in two ways.
One, to show progression as a product is making its way through our system (statuses bookmark, processing, approved. Once a product has a status of approved, it can’t move backward in the system (so that I don’t create a public 404). A product must have one of these three at all times to be valid.
I also use the statuses for different “flags” on the products:
retiredwhen a product is no longer available (this product will also always haveapprovedstatus;approved== publically indexable in our sitemap, butretiredremoves it from everywhere on our site (index, archives, etc) without 404’ing its permalink)pre-salewhen a product is not available yet (could have any of the three above)needs-images(could have any of the three)
My question is a bit of a two-parter:
-
Should I have just made the “flags” statuses booleans on the Product model? I ask because:
-
How do I write a scope that says
approved but not retired? Orapproved but not retired and not needs-images?
With a boolean, I can just have a scope like
scope :not_foo where(:foo = false) and chain those all up. I’m drawing a blank on the best way to do the same with the above setup. I thought the has_many :through setup was the way to go (the flags as booleans just seemed like a lot of excess falses in my database) but database structure/planning is not my strong suit.
I would suggest using state machine for the product flow
pre-sale,approvedandretiredand a boolean flag forneeds-imagesfor indicating additional state which is out of the flow.