Dadas las siguientes asociaciones, necesito hacer referencia a la Question
que Choice
se adjunta a desde el Choice
modelo. He estado intentando usar belongs_to :question, through: :answer
para realizar esta acción.
class User
has_many :questions
has_many :choices
end
class Question
belongs_to :user
has_many :answers
has_one :choice, :through => :answer
end
class Answer
belongs_to :question
end
class Choice
belongs_to :user
belongs_to :answer
belongs_to :question, :through => :answer
validates_uniqueness_of :answer_id, :scope => [ :question_id, :user_id ]
end
estoy obteniendo
NameError constante no inicializada
User::Choice
cuando trato de hacer current_user.choices
Funciona bien, si no incluyo el
belongs_to :question, :through => :answer
Pero quiero usar eso porque quiero poder hacer el validates_uniqueness_of
Probablemente estoy pasando por alto algo simple. Cualquier ayuda sería apreciada.
Respuestas:
Una
belongs_to
asociación no puede tener una:through
opción. Es mejor que el almacenamiento en cachéquestion_id
enChoice
y la adición de un índice único a la tabla (sobre todo porquevalidates_uniqueness_of
es propenso a las condiciones de carrera).Si es paranoico, agregue una validación personalizada
Choice
que confirme que las respuestasquestion_id
coinciden, pero parece que el usuario final nunca debería tener la oportunidad de enviar datos que crearían este tipo de desajuste.fuente
También puedes delegar:
fuente
Simplemente use en
has_one
lugar debelongs_to
en su:through
, así:Sin relación, pero dudaría en usar validates_uniqueness_of en lugar de usar una restricción única adecuada en su base de datos. Cuando haces esto en rubí tienes condiciones de carrera.
fuente
autosave: false
esté configurada.Mi enfoque era hacer un atributo virtual en lugar de agregar columnas de base de datos.
Este enfoque es bastante simple, pero viene con compensaciones. Requiere que Rails se cargue
answer
desde la base de datos, y luegoquestion
. Esto puede optimizarse más tarde cargando ansiosamente las asociaciones que necesita (es decirc = Choice.first(include: {answer: :question})
), sin embargo, si esta optimización es necesaria, entonces la respuesta de stephencelis es probablemente una mejor decisión de rendimiento.Hay un momento y un lugar para ciertas opciones, y creo que esta opción es mejor cuando se realizan prototipos. No lo usaría para el código de producción a menos que supiera que era para un caso de uso poco frecuente.
fuente
Parece que lo que quieres es un usuario que tenga muchas preguntas.
La pregunta tiene muchas respuestas, una de las cuales es la elección del usuario.
¿Es esto lo que buscas?
Modelaría algo así en este sentido:
fuente
Por lo tanto, no puede tener el comportamiento que desea, pero puede hacer algo que se le parezca. Quieres poder hacer
Choice.first.question
lo que he hecho en el pasado es algo como esto
de esta manera, ahora puede llamar a la pregunta sobre Choice
fuente
El
has_many :choices
crea una asociación llamadachoices
, nochoice
. Intenta usar en sucurrent_user.choices
lugar.Consulte la documentación de ActiveRecord :: Associations para obtener información sobre la
has_many
magia.fuente