继承的 Trailblazer 操作的契约是否可以更改其超类定义的验证?
Can an inherited Trailblazer operation's contract alter validations defined by its superclass?
当一个Trailblazer操作被继承定义时,它继承它的superclass的契约:
class Create < Trailblazer::Operation
contract do
...
end
...
end
class Update < Create
...
end
继承的 Trailblazer 操作的合约是否可以更改其超级class定义的验证?
出现这个问题是因为创建操作的契约定义了一个强制性的属性,它需要在更新操作中是可选的:
validates :foo, presence: true
最初的想法是以某种方式反转继承class中的这个定义,但似乎没有办法做到这一点(有可能ignore a 属性 in the subclass (writeable:false
- book p61) 但似乎没有办法改变它的有效性标准)。
一种解决方案是在每个操作的合同中使用外部表单。通过将表单提取到外部 class,创建操作将像这样包含和扩充它:
contract Form do
validates :upload, presence: true
end
更新更新将简单地包含它:
contract Form
现在 Create
中添加的验证不适用于 Update
。
您可以通过向验证器添加 if
语句来实现您想要的结果:
class Create < Trailblazer::Operation
contract do
validates :upload, presence: true, if: Proc.new{ |record| !record.persisted? }
end
end
class Update < Create
end
仅当记录尚未保存到数据库时才运行验证,因此在更新操作期间将跳过验证。 (假设您正在使用 ActiveModel 并遵循正常的 CRUD 使用模式。)
当一个Trailblazer操作被继承定义时,它继承它的superclass的契约:
class Create < Trailblazer::Operation
contract do
...
end
...
end
class Update < Create
...
end
继承的 Trailblazer 操作的合约是否可以更改其超级class定义的验证?
出现这个问题是因为创建操作的契约定义了一个强制性的属性,它需要在更新操作中是可选的:
validates :foo, presence: true
最初的想法是以某种方式反转继承class中的这个定义,但似乎没有办法做到这一点(有可能ignore a 属性 in the subclass (writeable:false
- book p61) 但似乎没有办法改变它的有效性标准)。
一种解决方案是在每个操作的合同中使用外部表单。通过将表单提取到外部 class,创建操作将像这样包含和扩充它:
contract Form do
validates :upload, presence: true
end
更新更新将简单地包含它:
contract Form
现在 Create
中添加的验证不适用于 Update
。
您可以通过向验证器添加 if
语句来实现您想要的结果:
class Create < Trailblazer::Operation
contract do
validates :upload, presence: true, if: Proc.new{ |record| !record.persisted? }
end
end
class Update < Create
end
仅当记录尚未保存到数据库时才运行验证,因此在更新操作期间将跳过验证。 (假设您正在使用 ActiveModel 并遵循正常的 CRUD 使用模式。)