1

I have a question very similar to this one: Rails normalize before find_or_create, but the solution given here is not working.

I have this model, where main_triggers_text is an array of strings that I want to be unique. In order to have ["one","two"] be the same as ["two","one"], Im normalizing (downcasing, sorting, etc) the data with a before_validation: call. Thats working fine.

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

But if I have ["one","two"] already inserted, and then I do this:

@main_trigger = MainTrigger.find_or_create_by(main_triggers_text: params[:main_triggers_text])

with the vector ["two","one"] It fails because it cant find the record in the database (data not normalized), but when it tries to insert it the data has been normalized and it cant create it because of the uniqueness constraint.

If I manually normalize before the find_or_create_by call, it does find the record. is there any way I can call the normalization function before the find_or_create? Right now the normalization function is just been called before the create part

1 Answer 1

1

There is no such thing as a before_find. Therefore implement the normalizer as a public function for re-use:

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

Then use it when finding:

@main_trigger = MainTrigger.find_or_create_by(main_triggers_text: MainTrigger.normalize_main_triggers_values(params[:main_triggers_text]))

As a general practice, it's best to cleanse your inputs before sending them to the DB.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.