Usando ActiveRecord belong_to con dos teclas
-
05-07-2019 - |
Pregunta
Tengo dos modelos ActiveRecord con una asociación hasMany / belongTo:
class User < ActiveRecord::Base
has_many :letters
end
class Letter < ActiveRecord::Base
belongs_to :user
end
El modelo de usuario tiene un atributo revision_number, al que me gustaría definir la asociación belong_to, por lo que la letra está asociada a un usuario por user.id y user.revision_number.
Intenté usar la clave de condiciones como se documenta en los documentos de la API:
class Letter < ActiveRecord::Base
belongs_to :user, :conditions => "revision_number = #{client_revision}"
end
pero esto intenta llamar a la revisión del cliente en la clase Letter, no en la instancia de Letter. ¿Alguien podría señalarme en la dirección correcta para determinar el alcance de la asociación belong_to correctamente?
Estoy usando el complemento actúa como revisable para la versión del usuario modelo.
Solución 2
Finalmente descubrí que lo que necesitaba era algo así como teclas compuestas, que Rails ActiveRecord no admite. La solución (al menos por ahora) era escribir accesos de cliente personalizados en la Carta para admitir las claves compuestas (id y número_revisión):
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 esta configuración, las letras del Cliente # 1. recuperarán una matriz de ambas letras, pero el Cliente de la Letra # 2. recuperará el Cliente # 1r2, mientras que el Cliente de la Letra # 2. recuperará el Cliente # 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
Todavía no estoy seguro de si este es el mejor enfoque para este problema, pero parece funcionar por ahora.
Otros consejos
Me está costando entender por qué querría abarcar el belong_to
de esta manera. Corrígeme si me equivoco, pero podría ser mejor hacer algo como esto. Supongo que desea algún tipo de sistema de control de versiones:
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