After_initialize will not resolve the n+1 issue with joins and includes.

Asked 2 years ago, Updated 2 years ago, 33 views

ruby 2.2.1p85
rails 4.2.1

Implemented with the following model configuration:

class Student
  after_initialize —set_profile
  has_one:student_profile, dependent::destroy

  default_profile
    self.student_profile||=StudentProfile.new
  end
end

class StudentProfile
  belong_to —student
end

In addition, if you want to solve the n+1 problem, after_initialize occurred first, and the n+1 problem was not resolved.

Student.joins(:student_profile)
Or
Student.includes(:student_profile)

I don't want to mess with after_initialize, but is there any other way to solve the n+1 problem?

Thank you for your cooperation.

ruby-on-rails ruby

2022-09-30 16:01

1 Answers

I think what I want to do is to make sure that the instance of StudentProfile is returned whenever I call Student#student_profile (I don't want nil).To achieve this, you can replace the student_profile method and initialize it for the first time when called.

class Student<ActiveRecord::Base
  has_one:student_profile, dependent::destroy

  def student_profile_with_init
    self.build_student_profile if not self.student_profile_without_init
    self.student_profile_without_init
  end

  alias_method_chain:student_profile,:init
end

With these settings, you can avoid N+1 by calling Student.eager_load(:student_profile) or Student.includes(:student_profile).

Notes

  • alias_method_chain causes student_profile_with_init to be student_profile and saves the original method as student_profile_without_init.
  • build_student_profile is an association automatically generated method, and what you are doing is the same as self.build_student_profile=StudentProfile.new.


2022-09-30 16:01

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.