Model self referential collections in Rails
- by Najitaka
I have written an application for an online clothing store in Rails 2.3.5. I want to show related Products when a customer views the Product Detail page.
For example, if the customer views the detail page for a suit, I'd like to display the accessory products that match the dress such as a vest, shoes, and belt. I have named the related products an Ensemble. However, the vest, shoes, and belts are also Products which is what has me struggling.
I have it working as follows but I know it's not the Rails way. I have a Products table for all of the products. Not important here but I also have a ProductDetails table. I have an Ensembles table that has the following columns:
product_id - the main or origination product, the one displayed on the detail page
outfit_id - the related or accessory product
In setting up the data, on the Products list, for each Product I have an Ensemble link. This link takes you to the index action in the Ensembles controller.
Using the id from the "main" Product, I find all of the associated Ensemble rows by product_id or I create a new ensemble and assign the id from the main product as the product_id. I'd like to just be able to do @product.related_products to get an Ensemble collection.
Also on the index page I list the columns of the main product so the user can be sure their main product was the one they selected from the list. I also have a select list of the other products, with an Add to Ensemble action.
Finally on the same index page, I have a table that displays the products that are already in the ensemble and in that list each row has a destroy link to remove a particular product from the ensemble. It would be nice if given a single Ensemble row @ensemble I could do @ensemble.product to get the Product related to the outfit_id of the ensemble row.
I've got it working without associations but I have to run queries in the controller to build my own @product, @ensemble, and @ensembles collections. Also the only way I found to destroy an ensemble row is by Ensemble.connection.delete(sql to delete), simple @ensemble.destroy doesn't work.
Anyone know how I would set up the associations or have a link to a site explaining a similar setup. None of the examples I found use the same table. They have A related to B through C. I want A related to other A through B.