Rails database setup Polymorphism

我只是一个虾纸丫 提交于 2019-12-25 18:28:39

问题


We have to create a request system which will have roughly 10 different types of requests. All of these requests will belong to the 'accounting' aspect of our application. Therefore we've called them "Accounting requests".

All requests share maybe only a few columns and each has up to 20 columns individually.

We started to wonder if having separate tables for each request type would be practical in terms of speed when we start to have to do very complicated joins or queries, for example, fetching ALL requests types into a single table and then sorting it.

Maybe it would be easier to just use Single Table Inheritance since it will have a type column and we'd be using one table to store all 10 accounting request types.

What do you think regarding using STI for this many polymorphic associations and requirements?

Essentially, it would have models like so:

AccountingRequest
BillingRequest < AccountingRequest
CheckRequest < AccountingRequest
CancellationRequest < AccountingRequest

Each subclass has roughly 10+ fields.


Currently reading about Multiple Table Inheritance here. This seems like the solution that fits my requirements in this case. Not sure yet though.


回答1:


STI is a good fit if your models all share the same attributes.

However if your sub classes start having attributes specific to them and not applicable to others, then STI can result in a lot of null columns. In that case, I usually prefer to go with polymorphic association.

This railscast episode is a great example of the difference between the 2




回答2:


You can use STI in that situation. But making STI will require all the columns into one single table and that's not the good think. The table will go very large in the number of fields.

I think you should divide into two tables like as below...

  1. Request: A request table will be the polymorphic table which saved the information for the type of requests.

  2. RequestItem: The request item table will save all the 20 fields records into the table and will have a foreign key of request table. The request item table will have two fields into the database that's called key and value.




回答3:


It sounds do-able.

When I've looked into this, I found that making extensive use of value objects helped to control the non-applicability of some attributes to some of the types.

In my case I had types of products, some of which would not have particular measurements for example. In those cases I used a Null Object to indicate "Not applicable" where appropriate.

Edit: I also found the composed_of syntax very convenient: https://apidock.com/rails/ActiveRecord/Aggregations/ClassMethods/composed_of




回答4:


For now I'm using a bit of NoSQL for such cases. Postgresql's JSONB type allows to store multilevel ruby hash. It also provides rich functionality: DB level constraints, indexes and query operators.

So common attributes are stored in standard way and child specific - in jsonb. Then you can use whatever you need on top of this: STI, Value Objects pattern, serialization or just create scopes for each child. I prefer the last one - my models are thin, most of constraints are DB level and all business logic is in service classes.

Pros:

  1. Avoiding alter table on big tables when need to add one more child type
  2. Keeping my queries efficient
  3. Preventing storing and selecting unnecessary columns
  4. Serialization out of the box for JSON APIs

Cons:

  1. A bit of schemaless
  2. Vendor lock


来源:https://stackoverflow.com/questions/44802522/rails-database-setup-polymorphism

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!