Rails polymorphic association: Restrict allowed classes
Asked Answered
I

2

17

I want a class to belong_to other classes through a polymorphic association.

What is the best way to restrict the association to a specific list of classes?

I am considering using a custom validation method like so, but I don't know if this is really the best idea:

class Feature < ActiveRecord::Base
  belongs_to :featureable, polymorphic: true

  validate :featurable_is_of_allowed_class

  FEATURABLE_CLASSES = ["Country", "City", "Store", "Product"]

  def featurable_is_of_allowed_class
    if !FEATURABLE_CLASSES.include? featurable.class.name
      errors.add(:featurable, "class not allowed for association")
    end
  end
end
Immortelle answered 18/11, 2016 at 16:14 Comment(1)
if you are expecting the class to throw an error or some sort when another class has has_many :features, it's not possible.Pone
G
29

We used this validation (Rails 5) for polymorphic type:

ALLOWED_TYPES = %w(Star Planet).freeze

validates :moonable_type, inclusion: { in: ALLOWED_TYPES }
Goines answered 23/3, 2017 at 14:42 Comment(4)
validates :moonable_id, presence: true, numericality: { only_integer: true } is not necessary, because Rails already checks that the moonable record exists.Clavus
@PereJoanMartorell Thanks for letting me know that!Goines
huh, thoughts on how to allow nil? I guess you would do a custom validation for that?Porterporterage
@Porterporterage you can use the allow_nil option. ex: validates :size, inclusion: { in: ALLOWED_TYPES }, allow_nil: true Rails guideKostroma
A
0

Not so long ago I implemented this gem SafePolymorphic.

The benefit to just using a validates is that it's more concise, easier to read and you get some helpers like scopes.

class Feature < ActiveRecord::Base
    belongs_to :featureable, polymorphic: [Country, City, Store, Product]
end
Awash answered 16/11, 2023 at 19:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.