在find_or_create之前的rails before_validation

时间:2018-07-18 10:21:31

标签: ruby-on-rails activerecord

我有一个与此问题非常相似的问题: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之前调用规范化函数?现在,规范化函数只是在创建部件之前被调用

1 个答案:

答案 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]))

作为一般做法,最好在 将输入发送到数据库之前清除输入。