L'uso di ActiveRecord appartiene_to con due chiavi
-
05-07-2019 - |
Domanda
Ho due modelli ActiveRecord con un'associazione hasMany / appartieneTo:
class User < ActiveRecord::Base
has_many :letters
end
class Letter < ActiveRecord::Base
belongs_to :user
end
Il modello utente ha un attributo revision_number, al quale vorrei ambire l'associazione appartiene_to, quindi la lettera è associata a un utente sia user.id che user.revision_number.
Ho provato a usare la chiave: condition come documentato nei documenti API:
class Letter < ActiveRecord::Base
belongs_to :user, :conditions => "revision_number = #{client_revision}"
end
ma questo tenta di chiamare la revisione del client sulla classe Letter, non sull'istanza di Letter. Qualcuno potrebbe indicarmi la giusta direzione per individuare correttamente l'associazione appartiene_a?
Sto usando il plug-in act-as-revisable per versione dell'utente modello.
Soluzione 2
Alla fine ho capito che cosa avevo bisogno era qualcosa come le chiavi composite, che Rails ActiveRecord non supporta. La soluzione (almeno per ora) era quella di scrivere sulla lettera degli accessi client personalizzati per supportare le chiavi composite (id e revision_number):
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
Con questa configurazione, le Client # 1 recupereranno un array di entrambe le lettere, ma Letter # 2.client recupererà Client # 1r2, mentre Letter # 2.client recupererà Client # 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
Non sono ancora sicuro se questo sia l'approccio migliore a questo problema, ma sembra funzionare per ora.
Altri suggerimenti
Non riesco a capire perché vorresti definire il appartiene_to
in questo modo. Correggimi se sbaglio, ma potrebbe essere meglio fare qualcosa del genere. Presumo che tu voglia una sorta di sistema di controllo della versione:
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