У меня очень длинный метод, который создает массив команд. Каждая команда ассоциируется с несколькими пользователями. После того, как метод завершен и команды завершены, я пытаюсь сохранить всю эту информацию, используя как можно меньше вызовов БД.
Ассоциации:
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». Я также пытался загружать пользователей перед вызовом этого метода, но, возможно, я делаю это неправильно.
Могу ли я уменьшить количество вызовов, совершаемых здесь? Какую еще информацию мне было бы полезно включить в этот вопрос?
Заранее благодарим вас за понимание.