我创建了一个在我的生产环境中无效的自定义验证器/关注点。它适用于我的单元测试和我的开发(localhost)环境。
用户可以在UI中提交一些IP地址(以逗号分隔),然后传递给我关注:
因此,类似192.168.1.1-10,192.168.1.0/24,10.10.10.1
的内容会被发送到模型:
class Device < ApplicationRecord
validates :ips_scan, :ips_exclude, ip: true, on: :update
end
在我的concerns
文件夹中有一个名为ip_validator.rb
的文件:
class IpValidator < ActiveModel::Validator
def validate(record)
if record.ips_scan
ips = record.ips_scan.split(',')
ips.each do |ip|
/([0-9]{1,3}\.){3}[0-9]{1,3}(\/([1-2][0-9]|[0-9]|3[0-2]))?(-([0-9]{1,3}))?/ =~ ip
puts ip
record.errors.add(:ips_scan, 'is not valid') unless $LAST_MATCH_INFO
end
end
if record.ips_exclude
ips = record.ips_exclude.split(',')
ips.each do |ip|
/([0-9]{1,3}\.){3}[0-9]{1,3}(\/([1-2][0-9]|[0-9]|3[0-2]))?(-([0-9]{1,3}))?/ =~ ip
record.errors.add(:ips_exclude, 'is not valid') unless $LAST_MATCH_INFO
end
end
end
end
Device
控制器是:
class DevicesController < ApplicationController
before_action :set_device, only: %i[edit show update]
respond_to :html
def show; end
def edit; end
def update
if @device.update(device_params)
flash[:notice] = 'Successful update'
redirect_to request.referrer
else
flash[:warning] = 'Address formats allowed: x.x.x.x OR x.x.x.x-x OR x.x.x.x/x'
redirect_to request.referrer
end
end
private def set_device
@device = Device.find(params[:id])
end
private def device_params
params.require(:device).permit(:token, :nickname, :ips_scan, :ips_exclude, :status)
end
end
正如我所提到的,这在开发中有效,但生产中的日志只是在尝试更新时回滚:
I, [2018-04-28T13:09:02.478701 #1] INFO -- : Started PUT "/devices/2" for XX.XX.XXX.XX at 2018-04-28 13:09:02 +0000
I, [2018-04-28T13:09:02.479362 #1] INFO -- : Processing by DevicesController#update as HTML
I, [2018-04-28T13:09:02.479450 #1] INFO -- : Parameters: {"utf8"=>"✓", "authenticity_token"=>"4bxLD+Yg/m5N2OxjGui+7jSsZdnqC1uQ6LZNUhsm36kB+2Ge0a9V11LceKrtDIJwlWR7vH4xQydff21X8qx1kQ==", "device"=>{"nickname"=>"justin test", "ips_scan"=>"192.168.0.1-10", "ips_exclude"=>""}, "commit"=>"Save", "id"=>"2"}
D, [2018-04-28T13:09:02.481431 #1] DEBUG -- : User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 2], ["LIMIT", 1]]
D, [2018-04-28T13:09:02.482750 #1] DEBUG -- : Device Load (0.6ms) SELECT "devices".* FROM "devices" WHERE "devices"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
D, [2018-04-28T13:09:02.483744 #1] DEBUG -- : (0.2ms) BEGIN
D, [2018-04-28T13:09:02.485163 #1] DEBUG -- : User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
D, [2018-04-28T13:09:02.486314 #1] DEBUG -- : (0.2ms) ROLLBACK
我错过了什么?