首页 > 解决方案 > 通过关联使用 has_many 保存时检测到 Rails 急切加载

问题描述

Bullet gem 在创建时检测到急切加载。考虑以下模型:

class User < ActiveRecord::Base
  has_many :user_banks
  has_many :banks, through: :user_banks
end

class Bank < ActiveRecord::Base
  belongs_to :country
  belongs_to :currency

  has_many :user_posts
  has_many :users, through: :user_banks
end

class UserBank < ActiveRecord::Base
  belongs_to :user
  belongs_to :bank
end

在我的控制器中,创建用户时:

  # GET /user/new
  def new
    @user = User.new
  end

  # POST /users
  def create
    @user = User.new(user_params)

    if @user.save
      redirect_to user_path(@user), notice: I18n.t('views.action.created')
    else
      render :new
    end
  end

  private

  def user_params
    params.fetch(:user, {}).permit(:name, :email, bank_ids: [])
  end

我有一个错误;

Bullet::Notification::UnoptimizedQueryError:
  user: ruby
  POST /admin/users
  USE eager loading detected
    Bank => [:country]
    Add to your query: .includes([:country])
  Call stack
    /src/app/controllers/admin/users_controller.rb:36:in `create'

不幸的是,通过关联急切加载 has_many 的 Rails 代码有点错误。我该如何解决这个问题?急切加载. country_currencyBank

如果您将在 Rails 控制台中尝试这样的事情;

[1] pry(main)> User.new(name: 'test', email: 'test@test.com', bank_ids: [1, 2]).save!

  Country Load (1.3ms)  SELECT `countries`.`id`, `countries`.`created_at`, `countries`.`updated_at`, `countries`.`code` FROM `countries` WHERE `countries`.`id` = 1 LIMIT 1
  Currency Load (0.4ms)  SELECT `currencies`.* FROM `currencies` WHERE `currencies`.`id` = 1 LIMIT 1
  Country Load (1.3ms)  SELECT `countries`.`id`, `countries`.`created_at`, `countries`.`updated_at`, `countries`.`code` FROM `countries` WHERE `countries`.`id` = 1 LIMIT 1
  Currency Load (0.4ms)  SELECT `currencies`.* FROM `currencies` WHERE `currencies`.`id` = 1 LIMIT 1
  User Create (0.5ms)  INSERT INTO `users` (`name`, `email`, `created_at`, `updated_at`) VALUES ('test', 'test@test.com', '2020-06-25 06:18:50', '2020-06-25 06:18:50')
  UserBank Create (1.0ms)  INSERT INTO `user_banks` (`user_id`, `bank_id`, `created_at`, `updated_at`) VALUES (1, 1, '2020-06-25 06:18:50', '2020-06-25 06:18:50')
  UserBank Create (0.4ms)  INSERT INTO `user_banks` (`user_id`, `bank_id`, `created_at`, `updated_at`) VALUES (1, 2, '2020-06-25 06:18:50', '2020-06-25 06:18:50')

标签: ruby-on-railsruby

解决方案


尝试:

User.new(name: 'test',
         email: 'test@test.com',
         banks: Bank.eager_load(:country, :currency).find([1, 2])
        ).save!

推荐阅读