我有以下用例:我有一个API和一个UI,它们都修改了相同类型的对象Vehicle。然而,当从UI修改车辆时,它必须提供车辆识别号码,而如果它被修改,则该号码可能尚未被知道,因为它尚未被标记在发动机缸体上(这显然是制造的)例子)。
所以我的模型是:
class Vehicle < ActiveRecord::Base
after_initialize :set_ivars
def set_ivars
@strict_vid_validation = true
end
validate :vid, length: {maximum: 100, minimum: 30}, presence: true, if: lambda { |o| o.instance_variable_get(:@strict_vid_validation) }
validate :custom_vid_validator, unless: lambda { |o| o.instance_variable_get(:@strict_vid_validation) }
end
两个父控制器:
class ApplicationController < ActionController::Base
before_filter :set_api_filter
private
def set_api_filter
@api = false
end
end
以及ApiController
将@api
设置为true
以及以下车辆控制器:
class VehicleController < ApplicationController
cache_sweeper VehicleSweeper, only: [:create, :update]
def create
@vehicle = Vehicle.new
@vehicle.update_attributes(params[:vehicle])
end
end
与以下清道夫:
class VehicleSweeper < ActionController::Caching::Sweeper
observe Vehicle
def before_validation(vehicle)
if self.instance_variable_get(:@api)
vehicle.instance_variable_set(:@strict_vid_validation, false)
else
vehicle.instance_variable_set(:@strict_vid_validation, true)
end
end
有点类似ApiVehicleController
然而,这不起作用。通过调试我发现:
1)清扫程序中的before_validation
(也没有配置任何其他回调)方法永远不会运行
2)总是触发更严格的ui验证,这是由于
3)在if上的lambda内:在validate上,instance_variable总是为true,因为它永远不会通过回调方法设置
为什么这不起作用?我该如何解决?如果没有,我可以采取不同的方法吗?
答案 0 :(得分:0)
最后,以下工作:
def my_controller_action
@vehicle = Vehicle.new
@vehicle.assign_attributes(params[:vehicle])
VehicleSweeper.send(:new).pick_a_validation(@vehicle)
@vehicle.save
end
并且在扫地机中移除线
observe Vehicle
并将before_validation
方法重命名为pick_a_validation
。
当然这只有效,因为我想做一个before_validation
。如果我想说after_validation
我不知道怎么会攻击它。
在任何一种情况下,我都希望听到如何在不绕过回调链的情况下完成这项工作。