问题
I have a Question
that has_many :answers
(just like SO). I also want each question to have only 1 accepted_answer
, so I just added an :accepted
attribute to the Answer
model that is simply a boolean.
So now, to get the accepted answer for my question, I have written a method on my model that just does this:
def accepted_answer
answers.where(accepted: true)
end
That allows me to do question.accepted_answer
and it returns an ActiveRelation object like you would expect.
Nothing fancy. Simple and effective.
However, what I want to ensure though is that there can only be one answer on each question that is accepted: true
at any moment in time.
What's the best way to approach this?
I thought about using a validator, but I couldn't find one that handled associated objects in this way. There are some that have bits & pieces that are interesting, but I can't quite fit all the pieces together. For instance, presence is interesting as is absence and validates_with (but this last one feels too heavy).
Suggestions?
回答1:
Most likely the best way would be to use after_add
callback (an example here), which would set to false all your existing accepted
records via update_all and the latest answer with accepted set to true. It all depends on your logic.
You can also employ some other callbacks such as before_save, before_update and such with the similar functionality depending on your application specifics.
It is not quit a validation, but it will effectively maintain the required state of your model. Besides, the purpose of the validations to warn you when something is not valid, but I guess you want to save your object without such failures, and just enforce a single accepted answer.
Let me know in case you want to stop adding answers after the first one was accepted. In this case it would require a different functionality.
来源:https://stackoverflow.com/questions/37964966/is-there-a-validation-i-can-use-for-a-specific-attribute-on-all-associated-recor