Search code examples
ruby-on-railsassociationsmodels

Review model - shared across two different other models


I am making an application that lets people list food items that they want to sell. They list Dishes (Dish model) and when people buy it, an Order record is created.

I want people to be able to submit reviews on Dishes if they have purchased it, and also review the Order (the order involves meeting the person).

I was wondering if I could create an Review model as follows:

class Review < ActiveRecord::Base
    belongs_to :dish
    belongs_to :order
end

I feel like this isn't right. The reviews on Dishes and the reviews on Orders will have different fields and potentially a completely different kind of logic, but at the same point in time its the same "idea" so I thought it would be better to create only one model for it.

Is the above correct?

Thanks


Solution

  • This is the use case that single table inheritance (STI) was designed for. When most of the values are shared between two models, STI can let you inherit both of them from another model. E.g.:

    class Review < ActiveRecord::Base; end
    
    class DishReview < Review
      belongs_to :dish
    end
    
    class OrderReview < Review
      belongs_to :order
    end
    

    You then store the review type in a new type column, and ActiveRecord handles storing them both in the same reviews table. The reviews table will need foreign keys for both a dish and an order.

    If these review types may diverge much ... say you want to add spicyness and sweetness, etc. to dish reviews, and speed and friendliness, etc., to the order reviews ... then it makes more sense to start with separate tables, one for DishReview and another for OrderReview. You can then use modules, services, concerns, etc., to share logic between them. You can also store common data in the Review table and have DishReview and OrderReview link one-to-one with that.