Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to model polymorphic types #58

Closed
kaelumania opened this issue May 19, 2020 · 4 comments
Closed

How to model polymorphic types #58

kaelumania opened this issue May 19, 2020 · 4 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@kaelumania
Copy link

I have a type X and X has one Y, but Y can be Y1 or Y2 or Y3, and each of them has different attributes, but they all subclass Y_base

@DmitryTsepelev
Copy link
Owner

Hi @kaelumania!

It's not possible right now: there is no way to build polymorphic types and let gem know how to decide what type should be used.

It could work like this (we define polymorphic type and use it in model):

# regular model definition
class Product < ApplicationRecord
  attribute :configuration, Configuration.to_array_type
end

class ConfigurationV1
  include StoreModel::Model

  # ...
end

class ConfigurationV2
  include StoreModel::Model

  # ...
end

class Configuration
  include StoreModel::PolymorphicModel

  def self.resolve(json)
    json[:version] == '1' ? ConfigurationV1 : ConfigurationV2
  end
end

In order to add the support we need to implement StoreModel::PolymorphicModel and handle it in ArrayType#cast_value

Please let me know if you want to try it out and I'll be happy to help 🙂

@DmitryTsepelev DmitryTsepelev added enhancement New feature or request help wanted Extra attention is needed labels May 19, 2020
@kaelumania
Copy link
Author

kaelumania commented May 19, 2020

Thanks for the fast response :) it don't have to be an array type though. I would suggest to use the same naming as for single table inheritance in active record json[:type]. What do you think about:

# regular model definition
class Product < ApplicationRecord
  attribute :configuration, Configuration.to_type, polymorphic: true
end

class ConfigurationV1 < Configuration
  # ...
end

class ConfigurationV2 < Configuration
  # ...
end

class Configuration
  def self.resolve(json)
    find_subclass(json[:type])
  end
end

@DmitryTsepelev
Copy link
Owner

Yeah, it definitely should work with a singular associations too. attribute method is a part of Rails Attributes API so it's hard and error–prone (in future) to add params to it, that's why I try to pack the logic into the type class as much as possible 🙂 Maybe we could allow to build resolve dynamically (by the way, I think it's not even required to be a subclass):

class Product < ApplicationRecord
  attribute :configuration, StoreModel.polymorphic { |json| "#{json.type}".constantize }
end

@DmitryTsepelev
Copy link
Owner

Added in #61

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants