Utiliser ActiveRecord appartient à deux clés
-
05-07-2019 - |
Question
J'ai deux modèles ActiveRecord avec une association hasMany / apartmentsTo:
class User < ActiveRecord::Base
has_many :letters
end
class Letter < ActiveRecord::Base
belongs_to :user
end
Le modèle utilisateur a un attribut revision_number, auquel je souhaiterais définir l’association apart_to, de sorte que la lettre est associée à un utilisateur à la fois par user.id et user.revision_number.
J'ai essayé d'utiliser la clé: conditions décrite dans la documentation de l'API:
class Letter < ActiveRecord::Base
belongs_to :user, :conditions => "revision_number = #{client_revision}"
end
mais cela tente d'appeler client-revision sur la classe Letter, pas l'instance de Letter. Quelqu'un pourrait-il m'indiquer la bonne direction pour définir correctement la relation association_appartements?
J'utilise le plug-in actes-comme-révisable pour la version de l'utilisateur. modèle.
La solution 2
Finalement, j'ai compris que j'avais besoin de quelque chose comme des clés composites, ce que Rails ActiveRecord ne prend pas en charge. La solution (pour le moment du moins) consistait à écrire des accesseurs client personnalisés sur la lettre pour prendre en charge les clés composites (id et numéro_de_vision):
class Letter < ActiveRecord::Base
def client
Client.find_by_id(self.client_id).try(:find_revision, self.client_revision)
end
def client=(c)
self.client_id = c.id
self.client_revision = c.revision_number
end
end
class Client < ActiveRecord::Base
acts_as_revisable
has_many :letters
end
Avec cette configuration, les clients 1.les clients vont récupérer un tableau des deux lettres, mais la lettre 2.client va récupérer le client n ° 1r2, tandis que la lettre n ° 2.client récupérera le client n ° 1r4:
Client id: 1 1 1 1 1 1
rev_number: 1 2 3 4 5 6
Letter id: 1 2
client_id: 1 1
client_revision: 2 5
Vous n'êtes toujours pas sûr qu'il s'agisse de la meilleure approche à ce problème, mais cela semble fonctionner pour le moment.
Autres conseils
J'ai de la difficulté à comprendre pourquoi vous souhaitez définir le appartient_à
de cette manière. Corrigez-moi si je me trompe, mais il serait peut-être préférable de faire quelque chose comme ça. Je suppose que vous voulez une sorte de système de contrôle de version:
class User < ActiveRecord::Base
has_many :letters
end
class Letter < ActiveRecord::Base
has_many :revisions, :class_name => "LetterVersion"
belongs_to :current, :class_name => "LetterVersion"
end
class LetterVersion < ActiveRecord::Base
belongs_to :letter
end