ruby-on-rails - 如何在 Rails 中手动导致 ActiveRecord RecordInvalid
问题描述
条目:我有从其中一种类型派生的属性类,ActiveRecord
并实现方法 cast(value) 将提供的值转换为派生的 Active Record 类型。在我们的例子中,我们仅在提供的值是 String 时执行转换,否则执行默认的整数转换。私有方法to_minutes
将格式化时间转换为表示花费分钟数的整数。我以为1d = 8h = 480m
。例如to_minutes
('1d 1h 1m') = 541 的结果。(我在 Ruby on Rails 5 ActiveRecord 中使用了这个资源自定义属性
如果string
来的没有数字,我需要返回一个验证错误,并将这个错误设置为@card.errors
. 我该怎么做?我尝试:
if time.scan(/\d/).empty?
raise ActiveRecord::RecordInvalid.new(InvalidRecord.new)
end
但它不起作用,我得到一个错误
NameError in CardsController#update
uninitialized constant CardDuration::Type::InvalidRecord
Extracted source (around line #15):
我为整数类型创建了自己的属性:
class CardDuration
class Type < ActiveRecord::Type::Value
def cast(value)
if value.is_a?(String)
to_seconds(value)
else
super
end
end
private
def to_seconds(time)
if time.scan(/\d/).empty?
return raise ActiveRecord::RecordInvalid.new, { errors: {message: 'Duration is too short (minimum is 1 number)'} }
end
time_sum = 0
time.split(' ').each do |time_part|
value = time_part.to_i
type = time_part[-1,1]
case type
when 'm'
value
when 'h'
value *= 60
when 'd'
value *= 8*60
else
value
end
time_sum += value
end
time_sum
end
end
end
和内部模型:
class Card < ApplicationRecord
validates :duration, length: { within: 0..14880 }
attribute :duration, CardDuration::Type.new
end
验证也不起作用,我不明白为什么。谢谢)在控制器内部,这个字段只能更新,所以我需要将错误设置为@card.errors:
class CardsController < ApplicationController
def update
if @card.update(card_params)
flash[:success] = "Card was successfully updated."
else
flash[:error] = @card.errors.full_messages.join("\n")
render status: 422
end
rescue ActiveRecord::RecordInvalid => e
return e.record
end
end
解决方案
在 ActiveRecord::RecordInvalid.new(...) 中,您需要传递具有方法“错误”文档的结构。尝试raise ActiveRecord::RecordInvalid.new(self.new)
使用方法编写或拥有类,errors
这将处理您的异常
推荐阅读
- python - 在 cpp 中使用 boost python 的 python 代码是否进行动态内存分配?
- arrays - 错误使用尺寸输入必须是整数?
- python - pyarrow.parquet.write_to_dataset() 使用 partition_cols 时速度极慢
- c++ - 使用 std::tie 进行类似 golang 的错误处理同时返回结果是否有缺点?(C++11)
- c# - 定时器结合 Application.DoEvents 不工作
- reactjs - 对点击放置图像做出反应
- visual-studio - 新项目列表未填充 v2 (.NET Core)
- node.js - 使用 Google Functions & Node JS 10 复制整个源文件夹而不仅仅是触发器文件
- c# - 如何使 checkBoxList 项目只读或将其删除?
- github - 在 Github 操作/工作流中使用 ddev