0

我遇到了一个问题,我认为我的解决方案目前非常难看,有什么更好的方法可以使用 rails/mongoid 执行以下操作?基本上,用户可以进来并提供一个“nil”的 answer_id,但是一旦他们回答了问题,我们就想锁定他们的第一个非 nil 答案。

controller.rb

r = Response.new(user: current_user, question_id: qid, answer_id: aid)
r.save_now!

以及以下 response.rb 模型:

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

所以我想允许 answer_id 最初为零(如果用户跳过了问题),然后取第一个非零的答案。

我真的不认为两次实例化 Response 对象是直观和干净的,一次在控制器中,一次在模型中,但我不确定最好的方法是什么?谢谢。

4

2 回答 2

1

(user, question_id, answer_id). 这样只有第一次插入会成功。后续插入将失败并出现错误。这消除了在您的方法中find查询的需要。save_now!

记得在安全模式下运行这个插入,否则你不会得到异常,它只会默默地失败。

更新

似乎您的问题可以通过重命名方法来解决。:) 看一看:

class Response
  def self.save_answer(user, qid, aid)
      resp = Response.where({user_id: user._id, question_id: qid}).first

      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
end

# controller.rb
r = Response.save_answer(current_user, qid, aid)
于 2012-07-11T16:18:11.733 回答
-1

Mongoid 对您可以使用的唯一性进行了验证。在您的情况下,您可以在 user、question_id 和 answer_id 上创建一个复合索引,并且不需要编写 save_answer 方法。

例如,您可以将其放入响应模型中:

validates_uniqueness_of :user_id, :question_id

确保您对每个用户的问题只能有一个响应。

于 2012-07-11T18:13:37.010 回答