[RUBY] [Rails] Difference in behavior between delegate and has_many-through in the case of one-to-one-to-many

Suppose you have a model with a one-to-one-to-many relationship as shown below.

class User
  has_one :examinee
end

class Examinee
  belongs_to :user
  has_many :tests
end

class Test
  belongs_to :examinee
end

So how do you implement it when you want to get the relevant Test model from the User model?

There are many ways to do this, but I think you often use ActiveRecord's convenience feature delegate or has_many-through. Both can achieve what you want to do, but the queries that are issued are slightly different, so I will introduce them.

delegate

You can use delegate to delegate a method to another class. See the Rails guide for more details. 3.4.1 delegate

In this case, implement as follows.

app/models/user.rb


delegate :tests, to: :examinee

When executed, two queries will be issued as shown below. The behavior is to first get the delegate examinee (first query) and then execute examinee.tests (second query).

irb> user.tests
Examinee Load SELECT `examinees`.* FROM `examinees` WHERE `examinees`.`user_id` = 1 LIMIT 1
Test Load SELECT `tests`.* FROM `tests` WHERE `tests`.`examinee_id` = 1

has_many-through

has_many-through is often used in many-to-many cases, but it can also be used in one-to-many cases like this one.

See the Rails guide for more details. 2.4 has_many: through association

In this case, implement as follows.

app/models/user.rb


has_many :tests, through: :examinee

When executed, one query will be issued as shown below. In this case, only one joined query will be issued. Considering that this function is implemented so that it corresponds to many-to-many, you can understand that it is acquired by join because it can not be acquired efficiently in two stages like deletgate.

irb> user.tests
Test Load SELECT `tests`.* FROM `tests` INNER JOIN `examinees` ON `tests`.`examinee_id` = `examinees`.`id` WHERE `examinees`.`user_id` = 1

Finally

Whether it is better to get it with 2 queries or 1 query joined depends on the execution environment, so it is not possible to judge whether it is good or bad. In most cases, it doesn't matter which one you write, so it doesn't matter which one you write.

However, even if it looks like it is doing the same thing from a black box perspective, the queries issued internally may be different like this time. Occasionally, it would be interesting to check these small differences when considering the origin and purpose of the function.

Recommended Posts

[Rails] Difference in behavior between delegate and has_many-through in the case of one-to-one-to-many
[Rails / ActiveRecord] About the difference between create and create!
Difference between member and collection of rails routes.rb
[Rails] I learned about the difference between resources and resources
About the difference between classes and instances in Ruby
[Rails] What is the difference between redirect and render?
[Rails] I investigated the difference between redirect_to and render.
Rails: Difference between resources and resources
Understand in 3 minutes! A very rough explanation of the difference between session and cookie
[Rails] What is the difference between bundle install and bundle update?
About the difference between "(double quotation)" and "single quotation" in Ruby
[Ruby] About the difference between 2 dots and 3 dots of range object.
What is the difference between the responsibilities of the domain layer and the application layer in the onion architecture [DDD]
[Rails] Difference between find and find_by
Understand the difference between each_with_index and each.with_index
[rails] Difference between redirect_to and render
Output the difference between each field of two objects in Java
Difference between byCharWrapping and byWordWrapping of UI Label in Japanese display
Difference between final and Immutable in Java
The identity of params [: id] in rails
Difference between pop () and peek () in stack
Difference between isEmpty and isBlank of StringUtils
Difference between getText () and getAttribute () in Selenium
About the difference between irb and pry
Difference between "|| =" and "instance_variable_defined?" In Ruby memoization
Difference between EMPTY_ELEMENTDATA and DEFAULTCAPACITY_EMPTY_ELEMENTDATA in ArrayList
Difference between addPanel and presentModally of FloatingPanel
Difference between int and Integer in Java
[Rails] Difference between redirect_to and render [Beginner]
[Rails] I studied the difference between new method, save method, build method and create method.
Displaying the three-dimensional structure of DNA and proteins in Ruby-in the case of GR.rb
Understand the difference between int and Integer and BigInteger in java and float and double
The difference between puts and print in Ruby is not just the presence or absence of line breaks
[Java] Understand the difference between List and Set
[Order method] Set the order of data in Rails
[iOS] Understand the difference between frame and bounds
Difference between next () and nextLine () in Java Scanner
Understand the difference between abstract classes and interfaces!
What is the difference between SimpleDateFormat and DateTimeFormatter? ??
[Ruby] Difference between methods with and without self in the class. About class methods and instance methods.
[Rails] Difference between create method and new + save method
[Rails] Ranking and pagination in order of likes
Is there a performance difference between Oracle JDK and OpenJDK at the end of 2017?
Check the behavior of getOne, findById, and query methods in Spring Boot + Spring Data JPA
Summary of frequently used commands in Rails and Docker
[Ruby] I thought about the difference between each_with_index and each.with_index
One case of solving a migration error in Rails
What is the difference between a class and a struct? ?? ??
[For beginners] DI ~ The basics of DI and DI in Spring ~
What is the difference between System Spec and Feature Spec?
Get the name of the test case in the JUnit test class
Regarding the difference between the three Timeouts in Java's HttpClient
Difference between new and create in Rais action controller
Calculate the difference between numbers in a Ruby array
[Java] Difference between static final and final in member variables
Behavior is different between new and clear () of ArrayList
Compare the difference between dockerfile before and after docker-slim
[JAVA] What is the difference between interface and abstract? ?? ??
Verification of the relationship between Docker images and containers
What is the difference between skip and pending? [RSpec]
SSL in the local environment of Docker / Rails / puma