导轨中的正则表达式验证不起作用:允许使用空白值的唯一字母数字值

时间:2016-08-27 19:22:51

标签: ruby-on-rails regex validation

我的控制器的创建和更新方法无法正常工作。我的一个属性是优惠券代码。我希望优惠券代码为:

  • 唯一但允许空白或零值
  • 使用正则表达式将代码限制为大写字母,数字和下划线

目前,我有一些问题。我的模型叫做ClassPrice,它有两个属性:coupon_code& :cost_in_cents。问题是:

  • 当我尝试使用空白:coupon_code创建一个新的ClassPrice时,它会重新加载新操作,给我一条消息,表示我已成功,但新代码实际上并未保存。
  • 当我尝试使用空白:coupon_code更新现有ClassPrice时,它会给我验证错误并且不保存更改:"错误:仅允许使用超文本字母,数字或下划线。&# 34;

这是我的控制器:

class ClassPrice < ActiveRecord::Base
  has_many :class_section_prices
  has_many :class_sections, through: :class_section_prices
  after_initialize :init

  validates :coupon_code, uniqueness: true, allow_blank: true, allow_nil: true

  validates :coupon_code, format: { with: /\A[A-Z0-9_]+\z/,
    message: "ERROR: only allows upppercase letters, numbers or underscores." }

  def cost_in_dollars
    if self.amount_in_cents == 0 
      "FREE"
    else
      "$#{amount_in_cents / 100.0}0"
    end
  end

  def virtual_price_in_dollars
    amount_in_cents.to_d / 100 if amount_in_cents
  end

  def virtual_price_in_dollars=(dollars)
    self.amount_in_cents = dollars.to_d * 100 if dollars.present?
  end

  private

  def init
    self.coupon_code      ||= ""
    self.amount_in_cents  ||= 0
  end
end

这是我的模特:

class Admin::ClassPricesController < ApplicationController
  layout 'admin'
  before_action :full_authenticate

  def full_authenticate
    authenticate_user!
    if !current_user.is_admin?
      flash[:alert] = "Access denied."
      redirect_to root_url
    end
  end

  def index
    @class_prices = ClassPrice.all
  end


  def new
    @class_price = ClassPrice.new
  end

  def create
    if @class_price = ClassPrice.create(class_price_params)
      redirect_to new_admin_class_price_path(@class_price), notice: 'New class price created.'
    else
      render action: "new"
    end
  end

  def edit
    @class_price = ClassPrice.find(params[:id])
  end

  def update
    @class_price = ClassPrice.find(params[:id])
    if @class_price.update_attributes(class_price_params)
      redirect_to edit_admin_class_price_path(@class_price), notice: 'Class Price was successfully updated.'
    else
      render action: "edit"
    end
  end

  def destroy
    @class_price = ClassPrice.find(params[:id])
    if @class_price != nil
      @class_price.destroy
      redirect_to admin_class_prices_path(@class_section), notice: 'Class Price was deleted.'
    else
      redirect_to admin_class_prices_path(@class_section), notice: 'Class Price not found.'
    end
  end

  private

  def class_price_params
    params.require(:class_price).permit(:class_price_id, :amount_in_cents, :coupon_code, :virtual_price_in_dollars)
  end
end

知道问题出在哪里?

1 个答案:

答案 0 :(得分:1)

我在您的代码中看到了几个问题:

  1. allow_blank: true允许值为nil或空字符串,因此如果您有allow_nil
  2. ,则不必另外使用allow_blank
  3. 您在格式验证中缺少allow_blank
  4. 摆脱after_initialize回调。每次实例化ClassPrice对象时它都会启动。此外,当您从数据库中获取正确的记录时,它将具有空白coupon_code并且amount_in_cents设置为0
  5. 创建操作不正确。 ClassPrice.create将始终返回一个对象,无论它是否已保存到数据库。此对象将始终评估为true。您应该将其拆分为2行,首先构建一个对象并保存它。
  6. 所以你的验证应该是这样的

    validates :coupon_code, uniqueness: { allow_blank: true },
      format: { with: /\A[A-Z0-9_]+\z/, message: "ERROR: only allows upppercase letters, numbers or underscores.", allow_blank: true }
    

    你的创作:

    def create
      @class_price = ClassPrice.new(class_price_params)
      if @class_price.save
        redirect_to new_admin_class_price_path(@class_price), notice: 'New class price created.'
      else
        render action: "new"
      end
    end
    

    我希望我没有错过任何东西。