I have run into an issue and I think that my solution is very ugly at the moment, what is a better way I can do the following with rails/mongoid? Basically, a user can come in and provide a ‘nil’ answer_id, but as soon as they answer the question, we want to lock in their first, non-nil answer.
controller.rb
r = Response.new(user: current_user, question_id: qid, answer_id: aid)
r.save_now!
And the following response.rb model:
def save_now!
user = self.user
qid = self.question_id
aid = self.answer_id
resp = Response.where({user_id: user._id, question_id: qid}).first
# We accept the first answer that is non-nil,
# so a user can skip the question (answer_id=nil)
# And then return and update the answer_id from nil to 'xyz'
if resp.nil?
resp = Response.new(user: user, question_id: qid, answer_id: aid)
else
if resp.answer_id.nil? && aid.present?
resp.answer_id = aid
end
end
resp.save!
end
So I would like to allow for answer_id to be nil initially (if a user skipped the question), and then take the first answer that is non-nil.
I really don’t think it’s intuitive and clean to instantiate the Response object twice, once in controller and once in model but I’m not sure on the best way to do this? Thanks.
Create a unique index over
(user, question_id, answer_id). This way only the first insert will succeed. Subsequent inserts will fail with an error. This eliminates the need for thefindquery in yoursave_now!method.Remember to run this insert in safe mode, or else you won’t get an exception, it will just fail silently.
Update
Seems that your problem might be solved by renaming the method. 🙂 Take a look: