[RUBY] [Rails] Différence de comportement entre delegate et has_many-through dans le cas de one-to-one-to-many

Supposons que vous ayez un modèle avec une relation un-à-un-à-plusieurs comme illustré ci-dessous.

class User
  has_one :examinee
end

class Examinee
  belongs_to :user
  has_many :tests
end

class Test
  belongs_to :examinee
end

Alors, comment l'implémentez-vous lorsque vous souhaitez obtenir le modèle de test pertinent à partir du modèle utilisateur?

Il existe différentes façons de le faire, mais je pense que vous utilisez souvent la fonction pratique «déléguer» d'ActiveRecord ou «has_many-through». Les deux peuvent réaliser ce que vous voulez faire, mais les requêtes émises sont légèrement différentes, je vais donc les présenter.

delegate

Vous pouvez utiliser déléguer pour déléguer une méthode à une autre classe. Consultez le Guide des rails pour plus de détails. 3.4.1 delegate

Dans ce cas, procédez comme suit.

app/models/user.rb


delegate :tests, to: :examinee

Une fois exécutées, deux requêtes seront émises comme indiqué ci-dessous. Le comportement consiste à obtenir d'abord le candidat de la destination de délégation (première requête), puis à exécuter examinere.tests (deuxième requête).

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 est souvent utilisé dans les cas plusieurs-à-plusieurs, mais il peut également être utilisé dans les cas un-à-plusieurs comme celui-ci.

Consultez le Guide des rails pour plus de détails. 2.4 has_many: par association

Dans ce cas, procédez comme suit.

app/models/user.rb


has_many :tests, through: :examinee

Une fois exécutée, une requête sera émise comme indiqué ci-dessous. Dans ce cas, une seule requête jointe sera émise. Considérant que cette fonction est implémentée de manière à correspondre à plusieurs-à-plusieurs, vous pouvez comprendre qu'elle est acquise par jointure car elle ne peut pas être acquise efficacement en deux étapes comme deletgate.

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

finalement

S'il vaut mieux l'obtenir avec 2 requêtes ou 1 requête jointe dépend de l'environnement d'exécution, il n'est donc pas possible de juger si c'est bon ou mauvais. Dans la plupart des cas, peu importe celui que vous écrivez, donc peu importe celui que vous écrivez.

Cependant, même s'il semble faire la même chose du point de vue de la boîte noire, les requêtes émises en interne peuvent être différentes comme cette fois. Parfois, il serait intéressant de vérifier ces petites différences lorsque l'on considère l'origine et le but de la fonction.

Recommended Posts

[Rails] Différence de comportement entre delegate et has_many-through dans le cas de one-to-one-to-many
[Rails / Active Record] À propos de la différence entre créer et créer!
Différence entre le membre et la collection de rails routes.rb
[Rails] J'ai étudié la différence entre les ressources et les ressources
Différences entre les classes et les instances dans Ruby
[Rails] Quelle est la différence entre la redirection et le rendu?
Comprenez en 3 minutes! Une explication très approximative de la différence entre session et cookie
[Rails] Quelle est la différence entre l'installation et la mise à jour du bundle?
Quelle est la différence entre les responsabilités de la couche domaine et de la couche application dans l’architecture onion [DDD]
[Rails] Différence entre find et find_by
[rails] Différence entre redirect_to et render
Sortie de la différence entre chaque champ de deux objets en Java
Différence entre l'étiquette d'interface utilisateur par habillage de caractères et par habillage de mots dans l'affichage japonais
Différence entre final et immuable en Java
L'identité des paramètres de rails [: id]
Différence entre pop () et peek () dans la pile
Différence entre isEmpty et isBlank de StringUtils
Différence entre getText () et getAttribute () de Selenium
À propos de la différence entre irb et pry
Différence entre "|| =" et "instance_variable_defined?" Dans Ruby memo
Différence entre EMPTY_ELEMENTDATA et DEFAULTCAPACITY_EMPTY_ELEMENTDATA dans ArrayList
Différence entre int et Integer en Java
[Rails] Différence entre redirect_to et render [Débutant]
[Rails] J'ai étudié la différence entre une nouvelle méthode, une méthode de sauvegarde, une méthode de construction et une méthode de création.
Afficher la structure tridimensionnelle de l'ADN et des protéines dans Ruby-dans le cas de GR.rb
Comprendre la différence entre int et Integer et BigInteger en java et float et double
[Java] Comprendre la différence entre List et Set
[Order method] Définit l'ordre des données dans Rails
[iOS] Comprendre la différence entre le cadre et les limites
Différence entre next () et nextLine () dans Java Scanner
Comprenez la différence entre les classes abstraites et les interfaces!
Quelle est la différence entre SimpleDateFormat et DateTimeFormatter? ??
[Rails] Différence entre la méthode de création et la méthode nouvelle + sauvegarde
[Rails] Classement et pagination par J'aime
Existe-t-il une différence de performances entre Oracle JDK et OpenJDK à la fin de 2017?
Vérifiez le comportement de getOne, findById et des méthodes de requête avec Spring Boot + Spring Data JPA
Résumé des commandes fréquemment utilisées dans Rails et Docker
[Ruby] J'ai réfléchi à la différence entre each_with_index et each.with_index
[Pour les débutants] DI ~ Les bases de DI et DI au printemps ~
Quelle est la différence entre System Spec et Feature Spec?
Obtenez le nom du scénario de test dans la classe de test JUnit
Concernant la différence entre les trois Timeouts dans HttpClient de Java
Différence entre nouveau et créer dans le contrôleur d'action Rais
Calculer la différence entre les nombres dans un tableau Ruby
[Java] Différence entre statique final et final dans les variables membres
Le comportement est différent entre new et clear () de ArrayList
Comparez la différence entre dockerfile avant et après docker-slim
[JAVA] Quelle est la différence entre interface et abstract? ?? ??
Vérification de la relation entre l'image Docker et le conteneur
Quelle est la différence entre ignorer et en attente? [RSpec]
SSL dans l'environnement local de Docker / Rails / puma