web-dev-qa-db-fra.com

Rails has_one: par association

Rails a un has_one :through association qui aide à établir une association un à un avec un troisième modèle en passant par un deuxième modèle. Quelle est l'utilité réelle de cela en plus de créer une association de raccourcis, ce serait autrement une étape supplémentaire.

En prenant cet exemple du Rails guide :

class Supplier < ActiveRecord::Base
  has_one :account
  has_one :account_history, :through => :account
end

class Account < ActiveRecord::Base
  belongs_to :supplier
  has_one :account_history
end

class AccountHistory < ActiveRecord::Base
  belongs_to :account
end

pourrait nous permettre de faire quelque chose comme:

supplier.account_history

qui serait autrement atteint comme:

supplier.account.history

Si c'est uniquement pour un accès plus simple, techniquement, il pourrait y avoir une association un à un qui relie un modèle à un nième modèle passant par n-1 pour un accès plus facile. Y a-t-il autre chose que je manque à part le raccourci?

64
Anurag
  1. Logique, OK, cela peut sembler un peu faible pour cela, mais il serait logique de dire que "J'ai un fournisseur qui a un compte chez moi, je veux voir l'historique complet du compte de ce fournisseur" , il est donc logique pour moi de pouvoir accéder directement à l'historique du compte auprès du fournisseur.

  2. Efficacité, c'est pour moi la principale raison pour laquelle j'utiliserais :through, simplement parce que cela émet une instruction de jointure plutôt que d'appeler le fournisseur, puis account, puis account_history. remarqué le nombre d'appels à la base de données?

    • en utilisant :through, 1 appel pour obtenir le fournisseur, 1 appel pour obtenir account_history (Rails utilise automatiquement :join pour récupérer via le compte)

    • en utilisant l'association normale, 1 appel pour obtenir le fournisseur, 1 appel pour obtenir le compte et 1 appel pour obtenir account_history

C'est ce que je pense =) j'espère que ça aide!

51
Staelen

Je suis surpris que personne n'ait abordé les objets d'association .

UNE has_many (ou has_one) :through la relation facilite l'utilisation du modèle d'objet d'association, c'est-à-dire lorsque vous avez deux choses liées les unes aux autres, et que La relation elle-même a des attributs (c'est-à-dire une date à laquelle l'association a été établie ou lorsqu'elle expire).

C'est considéré par certains comme une bonne alternative au has_and_belongs_to_many Aide ActiveRecord. Le raisonnement derrière cela est qu'il est très probable que vous devrez changer la nature de l'association ou y ajouter, et lorsque vous êtes dans quelques mois dans un projet, cela peut être très douloureux si la relation a été initialement établie comme une has_and_belongs_to_many (le deuxième lien donne quelques détails). S'il est configuré initialement à l'aide d'un has_many :through relation, puis quelques mois dans le projet, il est facile de renommer le modèle de jointure ou d'y ajouter des attributs, ce qui permet aux développeurs de répondre plus facilement aux exigences changeantes. Planifiez le changement.

10
ryan0
  • Association inverse: considérons la situation classique utilisateur-appartenance-groupe. Si un utilisateur peut être membre de plusieurs groupes, alors un groupe a plusieurs membres ou utilisateurs, et un utilisateur a plusieurs groupes. Mais si l'utilisateur ne peut être membre que dans un seul groupe, le groupe a toujours de nombreux membres: class User has_one :group, :through => :membership mais class Group has_many :members, :through => memberships. Le modèle intermédiaire membership est utile pour garder une trace de la relation inverse.

  • extensibilité: a has_one :through la relation peut facilement être étendue et étendue à un has_many :through relation

9
0x4a6f4672