在运行时将自定义字段添加到类中,在Ruby中使用mongoid

时间:2012-12-11 04:43:47

标签: ruby-on-rails validation mongoid custom-fields

在一个项目中遇到了一个要求,其中应该根据他的公司向登录用户询问特定数据。此特定数据将是公司特定的,可以是强制性的或唯一的。这是我采取的方法。 1.使用三个字段定义模型:Label(字符串),Mandatory(布尔值),Unique(布尔值)。 2.然后公司的管理员可以输入所需的字段。例如:Label => "Employee number", Mandatory => true, Unique => false using a simple form. 3.在为登录用户创建另一份模型救赎优惠券时,应询问此数据。 4.因此,在初始化Redeemed Coupon模型期间,重新打开课程,并检查登录用户的公司。

 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

然而,验证验证了存在,并且唯一性不起作用,并给出了失败消息:未定义回调。这是在保存之前抛出的,当is_valid时?被称为对象。 解决这个问题 进入自定义验证

 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     

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

1 个答案:

答案 0 :(得分:0)

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