我有一个与此问题非常相似的问题:Rails normalize before find_or_create,但此处给出的解决方案无效。
我有这个模型,其中main_triggers_text是我想唯一的字符串数组。为了使["one","two"]
与["two","one"]
相同,我使用before_validation:调用对数据进行了规范化(小写,排序等)。没问题。
class MainTrigger < ApplicationRecord
before_validation :normalize_main_triggers_values
validates :main_triggers_text, uniqueness: true, presence: true
def normalize_main_triggers_values
self[:main_triggers_text] = main_triggers_text.map(&:downcase).map(&:strip).sort unless main_triggers_text.nil?
end
end
但是如果我已经插入["one","two"]
,然后执行此操作:
@main_trigger = MainTrigger.find_or_create_by(main_triggers_text: params[:main_triggers_text])
带有向量["two","one"]
的操作失败,因为它无法在数据库中找到记录(数据未规范化),但是在尝试插入记录时,数据已被规范化,并且由于唯一性约束而无法创建
如果我在find_or_create_by调用之前手动进行归一化,它将找到记录。有什么办法可以在find_or_create之前调用规范化函数?现在,规范化函数只是在创建部件之前被调用
答案 0 :(得分:0)
没有before_find
这样的东西。因此,将规范化器实现为可重复使用的公共功能:
class MainTrigger < ApplicationRecord
before_validation :normalize_main_triggers_values
validates :main_triggers_text, uniqueness: true, presence: true
def normalize_main_triggers_values
self[:main_triggers_text] = MainTrigger.normalize_main_triggers_values(main_triggers_text)
end
def self.normalize_main_triggers_values values
values.map(&:downcase).map(&:strip).sort unless values.nil?
end
end
然后在查找时使用它:
@main_trigger = MainTrigger.find_or_create_by(main_triggers_text: MainTrigger.normalize_main_triggers_values(params[:main_triggers_text]))
作为一般做法,最好在 将输入发送到数据库之前清除输入。