简体   繁体   中英

What is the best way to model the database here. Polymorphism or STI? Rails

I have three types of Hangout s: Home , Bar , Restaurant . What's a good way to model these three hangouts?

I am trying to model an airbnb like app where customers can rent or share hangouts. A home, bar, restaurant, and possibly more types of hangouta in the future are all open for sharing.

Is this a decent way to model this using polymorphism?

class Hangout < ApplicationRecord
  belongs_to :hangoutable, polymorphic: true
end

class Home < ApplicationRecord
   has_one :hangout, as: :hangoutable, dependent: :destroy
end

class Bar < ApplicationRecord
   has_one :hangout, as: :hangoutable, dependent: :destroy
end

...

The idea here is that the parent model is a Hangout which could be one of the three hangoutables . Is this correct? Complaints about this is that it's kind of inverted... Each Hangout has one hangout , but the hangout is supposed to be the parent, not the child as it is modeled here. Is this okay? Will this cause me problems down the line? Usually polymorphism is done with the polymorphic entity as the child (eg imageable belongs to a person, a place, a thing, etc.) but here I want Hangout to be the parent.

The underlying table for hangout would look like this:

 create_table "hangouts", force: :cascade do |t|
    t.string "hangoutable_type"
    t.bigint "hangoutable_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["hangoutable_type", "hangoutable_id"], name: "index_hangouts_on_hangoutable_type_and_hangoutable_id"
  end

STI was also suggested to me but after reading this I'm not sure if these tables will share the same data in the future. So I am hesitant to use STI.

What can I do?

Create a Hangout model only -- with eg an enum to distinguish Bar, Restaurant, etc.

If they turn out to have significant behavioural differences, you could convert them to STI later. (Or even, if you want to make life needlessly difficult, the approximation of Class Table Inheritance you've described above.)

But in the short term, you're going to be best served by having them all live in one table, and implemented by a single class. 95% of your functionality is going to be treating all hangouts as equivalent; the fact they get different UI icons (say) is not necessarily a class-level distinction.

Do not be too quick to create separate model classes for every noun in your domain: classes separate implemented behaviour only. Introduce more when there's weight for them to pull, and not before.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM