Rails делает три вызова в БД для сохранения одной ассоциации - PullRequest
1 голос
/ 07 ноября 2019

У меня очень длинный метод, который создает массив команд. Каждая команда ассоциируется с несколькими пользователями. После того, как метод завершен и команды завершены, я пытаюсь сохранить всю эту информацию, используя как можно меньше вызовов БД.

Ассоциации:

class Team < ApplicationRecord
    belongs_to :objective
    belongs_to :consultancy
    has_one :seminar, :through => :consultancy
    belongs_to  :consultant, class_name: "Student"
    has_and_belongs_to_many  :users
end 

class User < Application 
    attr_accessor       :remember_token, :activation_token, :reset_token
    before_save         :downcase_stuff
    before_validation   :check_title, :check_user_number, :check_username, :check_password
    before_create       :create_activation_digest
    after_create        :update_last_login

    has_and_belongs_to_many  :teams
end

Вот как я пытаюсь их сохранить:

    these_teams = []
    @teams.each_with_index do |team, index|
        these_teams[index] = Team.new(:consultancy_id => @consultancy.id, :consultant_id => team[:consultant_id], :objective_id => team[:objective_id], :bracket => team[:bracket])
        these_teams[index].user_ids = team[:user_ids]
    end

    Team.transaction do
        these_teams.each do |this_team|
            this_team.save!
        end
    end

Вот пример чтения sql при запуске этого кодана локальном сервере. Это только для одной из команд. Все это повторяется для всех двенадцати команд, которые я пытаюсь сохранить.

  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."username" = ? LIMIT ?  [["username", "jo16"], ["LIMIT", 1]]
  User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND ("users"."id" != ?) LIMIT ?  [["email", "example-22@railstutorial.org"], ["id", 16], ["LIMIT", 1]]
  Student Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE "users"."type" IN ('Student') AND "users"."username" = ? AND ("users"."id" != ?) LIMIT ?  [["username", "jo16"], ["id", 16], ["LIMIT", 1]]
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."username" = ? LIMIT ?  [["username", "kg19"], ["LIMIT", 1]]
  User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND ("users"."id" != ?) LIMIT ?  [["email", "example-25@railstutorial.org"], ["id", 19], ["LIMIT", 1]]
  Student Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE "users"."type" IN ('Student') AND "users"."username" = ? AND ("users"."id" != ?) LIMIT ?  [["username", "kg19"], ["id", 19], ["LIMIT", 1]]
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."username" = ? LIMIT ?  [["username", "es32"], ["LIMIT", 1]]
  User Exists (0.2ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND ("users"."id" != ?) LIMIT ?  [["email", "example-38@railstutorial.org"], ["id", 32], ["LIMIT", 1]]
  Student Exists (0.2ms)  SELECT  1 AS one FROM "users" WHERE "users"."type" IN ('Student') AND "users"."username" = ? AND ("users"."id" != ?) LIMIT ?  [["username", "es32"], ["id", 32], ["LIMIT", 1]]
  SQL (0.1ms)  INSERT INTO "teams" ("consultancy_id", "objective_id", "consultant_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["consultancy_id", 66], ["objective_id", 2], ["consultant_id", 16], ["created_at", 2019-11-07 03:57:17 UTC], ["updated_at", 2019-11-07 03:57:17 UTC]]
  SQL (0.1ms)  INSERT INTO "teams_users" ("user_id", "team_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["user_id", 16], ["team_id", 311], ["created_at", 2019-11-07 03:57:17 UTC], ["updated_at", 2019-11-07 03:57:17 UTC]]
  SQL (0.1ms)  INSERT INTO "teams_users" ("user_id", "team_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["user_id", 19], ["team_id", 311], ["created_at", 2019-11-07 03:57:17 UTC], ["updated_at", 2019-11-07 03:57:17 UTC]]
  SQL (0.1ms)  INSERT INTO "teams_users" ("user_id", "team_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["user_id", 32], ["team_id", 311], ["created_at", 2019-11-07 03:57:17 UTC], ["updated_at", 2019-11-07 03:57:17 UTC]]

Таким образом, кажется, что для каждого члена команды есть три отдельных вызова. Один для «User Load», один для «User Exists» и один для «Student Exists». Я также пытался загружать пользователей перед вызовом этого метода, но, возможно, я делаю это неправильно.

Могу ли я уменьшить количество вызовов, совершаемых здесь? Какую еще информацию мне было бы полезно включить в этот вопрос?

Заранее благодарим вас за понимание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...