0

私は、弁護士と法学生が法的な質問に答えることができるアプリケーションを持っています。彼らの答えは投票することができます。アプリケーションは、views/question/show.html.erb の各回答の横に、回答が投票されたかどうか、および誰 (弁護士または法学生) によって投票されたかを示します。ただし、非常に奇妙な動作をしています。現在、テストの質問で、弁護士が回答に賛成票を投じた場合、アプリケーションは賛成票を表示しませんが、学生が回答に賛成票を投じた場合、学生と弁護士の両方の投票が表示されますが、両方が学生として表示されます投票。

これは、質問に対するすべての回答を取得し、各回答が持つ投票の種類を照会する、質問コントローラーの表示アクションのコードです。

  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 に 1 つの結果が含まれていることが示されていますが、突然空の配列になっています。現在、この質問には 2 つの答えがあります。そのため、puts ステートメントが 2 回実行されますが、2 回目で空になる理由はわかりません。

[#<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 エラーを回避するためであることに注意してください。クエリの最後に「リロード」を置くと、whereそのエラーを回避できるという別のSOの回答が見つかりました。

私の弁護士投票と学生投票でこの奇妙な動作が発生する理由を説明してもらえますか。また、それを回避するために show アクションを書き直す方法を教えてください。前もって感謝します。

アップデート

これは、質問 62 に 2 つの回答があり、それぞれに 1 つの answer_vote があることを示すコンソール レコードです。回答票の 1 つは弁護士 (弁護士 = true) によるもので、もう 1 つは学生 (学生 = true) によるものでしたが、ドミトリーのソリューションを試した後でも、両方とも私のアプリケーションで学生の投票として表示されています。

>> 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
4

2 に答える 2

3

問題の 1 つは、次の繰り返しで @lawyervotes 配列を書き直すことです。方法の1つは、代わりに追加することです(次のようなものを使用します:

@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)
于 2013-05-08T19:18:09.927 に答える