Ruby on rails 在运行时使用Ruby和mongoid向类添加自定义字段

Ruby on rails 在运行时使用Ruby和mongoid向类添加自定义字段,ruby-on-rails,validation,mongoid,custom-fields,Ruby On Rails,Validation,Mongoid,Custom Fields,在一个项目中,我们遇到了一个需求,即登录用户应该被询问基于其公司的特定数据。此特定数据将是特定于公司的,并且可能是强制性的或唯一的。这就是我采取的方法。 1.将模型定义为包含三个字段:标签(字符串)、必需(布尔值)、唯一(布尔值)。 2.然后,公司管理员可以输入所需的字段。e、 g:Label=>“员工编号”,强制=>true,唯一=>false,使用简单的表单。 3.应在为登录用户创建另一个模型兑换优惠券记录时询问此数据。 4.因此,在初始化兑换优惠券模型、重新打开类以及检查登录用户的公司期间

在一个项目中,我们遇到了一个需求,即登录用户应该被询问基于其公司的特定数据。此特定数据将是特定于公司的,并且可能是强制性的或唯一的。这就是我采取的方法。 1.将模型定义为包含三个字段:标签(字符串)、必需(布尔值)、唯一(布尔值)。 2.然后,公司管理员可以输入所需的字段。e、 g:
Label=>“员工编号”,强制=>true,唯一=>false,使用简单的表单。
3.应在为登录用户创建另一个模型兑换优惠券记录时询问此数据。 4.因此,在初始化兑换优惠券模型、重新打开类以及检查登录用户的公司期间

 class RedeemedCoupon
  def initialize(attrs = nil, options = nil)
    super
    if Merchant.current #this is set in the application controller as thread specific variable

  coupon_custom_field = CouponCustomField.where(:merchant_id => Merchant.current).first
  if coupon_custom_field and coupon_custom_field.custom_fields.size > 0
    coupon_custom_field.custom_fields.each do |custom_field|
      class_eval do
        field custom_field.label.to_sym, :type => String
        attr_accessible custom_field.label.to_sym
      end
      if custom_field.unique
        class_eval do
          index custom_field.label.to_sym
          #validates_uniqueness_of custom_field.label.to_sym, :case_sensitive => false
        end
      end
      if custom_field.mandatory
        class_eval do
          #validates_presence_of custom_field.label.to_sym
        end
      end
    end
  end
end
结束

但是,验证验证的存在性和唯一性不起作用,并给出一条失败消息:callback not defined。这是在保存之前抛出的,什么时候有效?被称为对象。 解决这个问题 进行自定义验证

 validate :custom_mandatory_unique

 def custom_mandatory_unique
   if Merchant.current
     coupon_custom_field = CouponCustomField.where(:ira_merchant_id => Merchant.current).first
   if coupon_custom_field and coupon_custom_field.custom_fields.size > 0
     coupon_custom_field.custom_fields.each do |custom_field|
       field_value = self.send(custom_field.label.to_sym)
       self.errors.add(custom_field.label.to_sym, "cannot be blank") if !field_value.present? and  custom_field.mandatory

      if field_value.present? and custom_field.unique
        if RedeemedCoupon.where(custom_field.label.to_sym => field_value, :merchant_id => Merchant.current).size > 0
          self.errors.add(custom_field.label.to_sym, "already taken")
        end
      end
    end
  end 
end     
结束

我的问题是: 1.这是最好的方法吗。 2.是否已有宝石(已搜索,但无法获得)?
3.如何在此处使用验证帮助程序而不是定义单独的验证块?

我将定义一个模型,该模型存储与公司对应的属性映射集,以及一个保存其值并与优惠券模型关联的属性模型。然后在优惠券中创建一个自定义验证方法,确保基于公司id的所有require属性都存在,并创建一个根据公司关联构建这些属性的方法。

这是一种处理业务逻辑的极其复杂的方法。不应在运行时插入验证。当然你可以做到,但很难从多个方面证明它的合理性:性能、可维护性、你所看到的腐蚀?但它不包括验证。