简体   繁体   English

在Rails中验证多态关联类型

[英]Validating polymorphic association type in Rails

I am developing a controller that creates a model with a polymorphic belongs_to association. 我正在开发一个控制器,该控制器使用多态的belongs_to关联创建模型。 What I do now to find the model it belongs to is as follows: 我现在要找到它所属的模型的工作如下:

 def find_polymorphic_model(classes)
   classes_names = classes.map { |c| c.name.underscore + '_id' }

   params.select { |k, v| classes_names.include?(k) }.each do |name, value|
     if name =~ /(.+)_id$/
       return $1.classify.constantize.find(value)
     end
   end

  raise InvalidPolymorphicType
end

Where classes is an array of valid types for the association. 其中classes是关联的有效类型的数组。

The problem with this approach is that I have to remember in the controller which types are allowed for the model I am creating. 这种方法的问题在于,我必须记住控制器中要创建的模型允许使用的类型。

Is there a way to find which types are allowed for a certain polymorphic belongs_to association? 有没有一种方法可以找到某种多态的Emirates_to关联允许使用的类型? Or maybe I am doing this wrong and I should not let a polymorphic controller be exposed without nesting it in the polymorphic resource (in the router)? 还是我做错了,我不应该暴露多态控制器而不将其嵌套在多态资源中(在路由器中)?

I also think there may be problems with the fact that Rails lazy loads classes, so to be able to find out this thing I would have to explicitly load all models at initialization time. 我还认为Rails延迟加载类可能存在一些问题,因此要想发现这一点,我必须在初始化时显式加载所有模型。

For your validation you don't have to get all the possible polymorphic types. 为了进行验证,您不必获取所有可能的多态类型。 All you need is to check if the specified type (say, the value of taggable_type attribute) is suitable. 您只需要检查指定的类型 (例如, taggable_type属性的值)是否合适。 You can do it this way: 您可以这样操作:

# put it in the only_polymorphic_validator.rb. I guess under app/validators/. But it's up to you.
class OnlyPolymorphicValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
        polymorphic_type = attribute.to_s.sub('_type', '').to_sym
        specified_class = value.constantize rescue nil
        this_association = record.class.to_s.underscore.pluralize.to_sym

        unless(specified_class.reflect_on_association(this_association).options[:as] == polymorphic_type rescue false)
            record.errors[attribute] << (options[:message] || "isn't polymorphic type")
        end
    end
end

And then use: 然后使用:

validates :taggable_type, only_polymorphic: true

to check whether :taggable_type contains a valid class. 检查:taggable_type是否包含有效的类。

Answered too soon and didn't get that you are looking at polymorphic associations. 回答得太早了,并没有得到您正在查看的多态关联。

For associations in general, use reflect_on_all_associations . 对于一般的关联,请使用reflect_on_all_associations

However, for some polymorphic associations, there is no way to know all the classes which can implement the association. 但是,对于某些多态关联,无法知道所有可以实现关联的类。 For some others, you need to look at the type field. 对于其他一些,您需要查看类型字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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