第一个查询返回的条目,第二个查询为空

时间:2013-05-08 18:55:22

标签: ruby-on-rails

我有一个申请,允许律师和法律学生回答法律问题。他们的答案可以投票。除了views / question / show.html.erb上的每个答案旁边,申请表明答案是否已被投票,以及由谁(律师或法律学生)投票。然而,它表现得非常奇怪。目前,在一个测试问题上,如果律师投票给答案,申请书没有显示upvote,但如果学生投票给答案,那么学生和律师的投票都将显示,但两者都显示为学生票。

这是问题控制器的show动作中的代码,它检索问题的所有答案,然后查询每个答案的投票类型。

  def show

  @question = Question.find(params[:id])
  @answers = @question.answers

   @answers.each do |a|


       @lawyervotes = AnswerVote.where({:answer_id => a.id, :lawyervote => true}).reload
       puts @lawyervotes.inspect
       puts "lawyervotes"
       @studentvotes = AnswerVote.where({:answer_id => a.id, :studentvote => true}).reload
       @uservotes = AnswerVote.where({:answer_id => a.id, :lawyervote => nil, :studentvote => nil}).reload

    end 
  end

如果我在控制台中查看puts语句,它会显示@lawyervotes包含一个结果,但它突然变成一个空数组。目前,这个问题有两个答案,这就是为什么puts语句运行两次,但我不知道为什么它在第二次通过

时是空的
[#<AnswerVote id: 34, value: 3, answer_id: 54, user_id: 37, created_at: "2013-05-08 18:29:34", updated_at: "2013-05-08 18:29:34", lawyervote: true, studentvote: nil>]
lawyervotes
[]
lawyervotes

注意,我在每个查询结尾处放置reload的原因是为了避免我得到的ActiveRecord :: AssociationTypeMismatch错误,根据我发现的另一个SO回答,当您查询' “。我找到了另一个SO答案,说在where查询结束时加上'reload'可以帮助避免这个错误。

你能解释一下为什么这种奇怪的行为可能会发生在我的律师投票和学生投票中,并可能告诉我如何重写节目行动以避免它。提前谢谢。

更新

这是控制台记录,显示问题62有两个答案,每个答案都有一个answer_vote。其中一个答案是由律师(律师=真),而一个是由学生(学生=真),但是,他们在我的申请中都显示为学生投票,即使在尝试了dmitry的解决方案之后。

>> q = Question.find_by_id(62)
  Question Load (0.2ms)  SELECT "questions".* FROM "questions" WHERE "questions"."id" = 62 LIMIT 1
=> #<Question id: 62, details: "I have a terminal illness but don't have time to go...", question: "What happens if I die without a will?", user_id: 35, accepted_answer_id: nil, created_at: "2013-05-08 18:19:48", updated_at: "2013-05-08 18:19:48", city: "Toronto", province: nil, province_id: 6>
>> q.answers
  Answer Load (0.2ms)  SELECT "answers".* FROM "answers" WHERE "answers"."question_id" = 62
=> [#<Answer id: 54, content: "There is legislation that determines the rules of i...", accepted: nil, user_id: 50, question_id: 62, created_at: "2013-05-08 18:20:41", updated_at: "2013-05-08 18:20:41">, #<Answer id: 55, content: "Ontario has statutory provisions that detail who in...", accepted: nil, user_id: 37, question_id: 62, created_at: "2013-05-08 18:22:53", updated_at: "2013-05-08 18:22:53">]
>> a54 = Answer.find_by_id(54)
  Answer Load (0.3ms)  SELECT "answers".* FROM "answers" WHERE "answers"."id" = 54 LIMIT 1
=> #<Answer id: 54, content: "There is legislation that determines the rules of i...", accepted: nil, user_id: 50, question_id: 62, created_at: "2013-05-08 18:20:41", updated_at: "2013-05-08 18:20:41">
>> a54.answer_votes
  AnswerVote Load (0.2ms)  SELECT "answer_votes".* FROM "answer_votes" WHERE "answer_votes"."answer_id" = 54
=> [#<AnswerVote id: 34, value: 3, answer_id: 54, user_id: 37, created_at: "2013-05-08 18:29:34", updated_at: "2013-05-08 18:29:34", lawyervote: true, studentvote: nil>]
>> a55 = Answer.find_by_id(55)
  Answer Load (0.3ms)  SELECT "answers".* FROM "answers" WHERE "answers"."id" = 55 LIMIT 1
=> #<Answer id: 55, content: "Ontario has statutory provisions that detail who in...", accepted: nil, user_id: 37, question_id: 62, created_at: "2013-05-08 18:22:53", updated_at: "2013-05-08 18:22:53">
>> a55.answer_votes
  AnswerVote Load (0.3ms)  SELECT "answer_votes".* FROM "answer_votes" WHERE "answer_votes"."answer_id" = 55
=> [#<AnswerVote id: 35, value: 3, answer_id: 55, user_id: 50, created_at: "2013-05-08 18:37:32", updated_at: "2013-05-08 18:37:32", lawyervote: nil, studentvote: true>]

更新

我把这段代码放在循环中

   puts AnswerVote.where({:answer_id => a.id}).reload.inspect
   puts "inspectinganswervote"

并得到了这个结果

[#<AnswerVote id: 34, value: 3, answer_id: 54, user_id: 37, created_at: "2013-05-08 18:29:34", updated_at: "2013-05-08 18:29:34", lawyervote: true, studentvote: nil>]
inspectinganswervote
[#<AnswerVote id: 35, value: 3, answer_id: 55, user_id: 50, created_at: "2013-05-08 18:37:32", updated_at: "2013-05-08 18:37:32", lawyervote: nil, studentvote: true>]
inspectinganswervote

更新

Answer.rb

class Answer < ActiveRecord::Base
  attr_accessible :accepted, :content, :question_id, :user_id

  has_many :comments
  belongs_to :question
  belongs_to :user
  has_many :answer_votes
  has_and_belongs_to_many :watchers, :join_table => "answer_watchers", :class_name => "User"
  has_reputation :votes, source: :user, aggregated_by: :sum
  has_reputation :lawyervotes, source: :user, aggregated_by: :sum
  has_reputation :studentvotes, source: :user, aggregated_by: :sum
  has_reputation :best, source: :user, aggregated_by: :sum
  # 


  def add_to_watchers(user)
    self.watchers << user unless self.watchers.include?(user)
  end 

    after_create :creator_watches_me
  private 

  def creator_watches_me
    self.watchers << user unless self.watchers.include?(user)
  end 


end

AnswerVote.rb

class AnswerVote < ActiveRecord::Base
  attr_accessible :answer_id, :user_id, :value, :answer, :lawyervote, :studentvote

  belongs_to :answer
  belongs_to :user

  validates_uniqueness_of :answer_id, scope: :user_id
  validates_inclusion_of :value, in: [1,-1,10,-10, 3]
  validate :ensure_not_author

 scope :lawyers, where(lawyervote: true)
scope :students, where(studentvote: true)


  def ensure_not_author
    errors.add :user_id, "is the author of the answer" if answer.user_id == user_id
  end

end

2 个答案:

答案 0 :(得分:3)

其中一个问题 - 您在下一次迭代期间重写了@lawyervotes数组。其中一种方法是添加它(使用类似的东西:

@lawyervotes = []
@answers.each do |a|
  @lawyervotes <<= AnswerVote.where({:answer_id => a.id, :lawyervote => true}).reload
  ...
end

但它非常糟糕,非Rails风格。正如我上面提到的,你不需要通过@answers这个迭代,你只需写:

已更新

@lawyervotes = @question.answers.map {|a| a.answer_votes.lawyers}.reject!(&:empty?).flatten
@studentvotes = @question.answers.map {|a| a.answer_votes.students}.reject!(&:empty?).flatten

在你的AnswerVotes模型中:

scope :lawyers, where(lawyervote: true)
scope :students, where(studentvote: true)

答案 1 :(得分:0)

由于第二个答案只有一个lawyervotesAnswerVotelaywervote = nil :),您将studentvote = true数组设为空,因此投票存在于@studentvotes变量。

如果您同时检查@studentvotes,您将在循环的第二次迭代中看到第二次投票。