0

I have a table that stores in-app purchases. Model name is Item. It stores some thing like price, description, etc.

Now, there are a few different Item types. There are Themes and Settings. A theme example would be like Night Theme which changes the color of the app to very dark colors. A setting example would be like gold which gives the user premium access.

So in model Item, I need to store both the Themes and Settings, and possibly other purchases. When the user goes to the 'Store' in the app, it will pull in all items from Item.

However, if the user goes to their Account in the app, there is a "Themes" section and a "Settings" section.

I thought of using an actual_id on the Item model. I would create a new ItemType model. id=1, type=Theme, id=2, type=Setting. Then on Item, I would store both the item_type_id, and the actual_id. The actual_id would be a reference to the proper table. So if item.item_type_id = 1 (Theme), then actual_id would reference the Themes table. If item.item_type_id = 2 (Setting), then actual_id would reference the Settings table.

1) Is this a good way of setting things up? Can anyone think of anything better?

Here's some sample data to show what I mean.

ItemType

id|type :--|:-- 1|Theme 2|Setting

Theme

id|description|... :--|:--|:-- 1|Night Theme|... 2|Ice Theme|...

Setting

id|description|... :--|:--|:-- 1|Gold|... 2|Remove Ads|...

Item

id|actual_id|item_type_id|cost :--|:--|:--|:-- 1|1|1|99 2|2|1|99 3|1|2|299 4|2|2|99

Then, if the user goes to the "Themes" or "Settings" section, I will fetch from the Item table where item_type_id = appropriateSection, and then tie actual_id to the appropriate table's id. (I actually have a UserItem model that holds ownership as well as a Purchase model that holds purchase history, but for simplicity sake, let's just say we use Item table for this)

2) How would I create an ActiveModelSerializer around this? Typically, a serializer might look like this...

class Api::V1::ItemSerializer < ActiveModel::Serializer
  attributes :id, :cost
  has_one :item_type, serializer: Api::V1::ItemTypeSerializer
end

but how would we include the actual_id reference to either A) model Theme or B) model Setting ?

chris P
  • 6,359
  • 11
  • 40
  • 84
  • It sounds like you're trying to make a [polymorphic association](http://guides.rubyonrails.org/association_basics.html#polymorphic-associations), I've never used ActiveModelSerializers so can't help with that. – j-dexx Jun 02 '15 at 14:44

2 Answers2

1

Actually, I think what you are looking for is Single Table Inheritance: http://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Single+table+inheritance

This allows you to store multiple different subclasses of the same base class in the same table.

So, in your example, you would have the following models:

class Item < ActiveRecord::Base
end

class Theme < Item
end

class Setting < Item
end

Item becomes your base class for two other models (Theme and Setting), all of which will get stored in the same table (items).

The only thing you will need to add to your items table is a string column called "type". Rails / ActiveRecord handles setting that column to the appropriate thing (Theme or Setting) as well as scoping queries appropriately for you.

As for the ActiveModelSerializer part, you would just make separate serializers for each of the two subclasses.

0

This is a good use case for has_many_through.

Example

Community
  • 1
  • 1
Antarr Byrd
  • 24,863
  • 33
  • 100
  • 188