Массовая вставка с игнорированием повторяющихся записей

#ruby-on-rails #ruby #ruby-on-rails-6

#ruby-on-rails #ruby #ruby-on-rails-6

Вопрос:

Я пытаюсь выполнить массовую вставку на основе условия, при котором, если существует электронная почта, она должна игнорировать запись. В настоящее время мой подход немного длинный. Сначала я фильтрую электронную почту, которой нет в таблице users, а затем выполняю insert, который запускает несколько запросов insert. Я проверил в rails 6, что у нас есть insert_all и upsert_all, но не уверен, как мы можем добиться того же с помощью этих методов.

 user_email = ["aniket@rpxcorp.com", "assasdas@gmail.com"]

##Only find those users which doesn't exists in users table

user_email = user_email - User.all.pluck(:email)

records = []
role = Role.find_by(name: "admin")
user_email.each do |record|
    records.push({email: record, password: "12345678", password_confirmation: "12345678", role: role})
end

#it will run multiple insert commands which I want to avoid

u = User.create(records)
  

Комментарии:

1. Обычно вы используете find_or_create_by which can test перед созданием.

2. @tadman Работает ли это с несколькими записями? Кроме того, будет ли запускаться запрос с несколькими вставками или запрос с одной вставкой?

3. Почему бы не использовать insert_all тогда? Вы получаете исключение? Если да, то что? Вам нужно объяснить. В Rails insert_all должно сделать DO NOTHING это за вас.

4. Если для этого используется слой, подобный Devise, и password он обрабатывается моделью, то вы не можете использовать insert_all его в качестве обхода, вы должны использовать create и позволить before_validation крючкам сработать. insert_all Это вставка низкого уровня.

5. Devise выполняет много работы на уровне модели, которую вы не можете пропустить. Если у вас есть другие модели, которые являются просто «немыми данными», тогда это работает нормально.

Ответ №1:

Согласно комментариям @tadman для любой модели, поддерживаемой devise, мы не можем выполнять массовую вставку