2013-05-08 1 views
0

У меня есть приложение, которое позволяет юристам и студентам-юристам отвечать на юридические вопросы. Их ответы можно проголосовать. Помимо каждого ответа на views/question/show.html.erb, приложение указывает, был ли признан ответ и кто (юрист или студент юридического факультета). Однако, это ведет себя очень странно. В настоящее время, по тестовому вопросу, если адвокат голосует за ответ, в заявке не отображается надбавка, но если студент голосует за ответ, то будут показаны как голос студента, так и адвоката, но оба они отображаются как студент голосов.запись возвращена на первый запрос, пустой на второй

Это код в действии 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 

Если я смотрю в консоли для заявлений Кладет, это показывает, что @lawyervotes содержит один результат, но потом это вдруг пустой массив. В настоящее время существует два ответа на этот вопрос, поэтому оператор путы запускается в два раза, но я не знаю, почему она пуста на второй раз через

[#<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 может помочь избежать этой ошибки.

Можете ли вы объяснить, почему это странное поведение может происходить с моими адвокатами и студенческими голосами и, возможно, расскажите мне, как переписать действие шоу, чтобы избежать этого. Заранее спасибо.

Update

Это консольная запись, показывающее, что вопрос 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>] 

Update

Я ставлю этот код в цикле

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 

Update

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 
+0

Почему вы делаете 'reload' после того, как вы когда-либо отвечали на вопросы по запросу? – pungoyal

+0

@PuneetGoyal объясняется во втором-последнем абзаце OP. Пожалуйста, дайте мне знать, если это не ясно. – BrainLikeADullPencil

+0

появляется 'Ответ'' has_many' 'AnswerVote'. Не можете ли вы @lawyervotes = a.answer_votes.where (: lawyervote => true) '? – pungoyal

ответ

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) 
+0

упс, извините. Как получить локальную переменную 'a' (в a.answer_votes.lawyers) без прокрутки? Этот код находится в контроллере вопросов. Чтобы получить локальную переменную 'a', мне нужно пройти через '@answers = @ questions.answers', как показано в op – BrainLikeADullPencil

+0

Спасибо. Когда нет адвокатов, ваш код возвращает массив внутри массива, как этот '[[]]'. Поэтому, когда моя логика просмотра проверяет, есть ли голоса юриста, подобные этому '<% if @ lawyervotes.size === 1%>', он показывает, что есть 1 голос адвоката, хотя его нет. Это связано с расположением внутри массива. Вы знаете, как это исправить? – BrainLikeADullPencil

+0

Обновлен мой ответ. –

0

Вы получение массива lawyervotes пустым для второго ответа, поскольку второй ответ содержит только один AnswerVote с laywervote = nil и studentvote = true :) Итак, голосование присутствует в переменной @studentvotes.

Если вы проверите свой @studentvotes, вы увидите второе голосование, напечатанное на второй итерации цикла.

+0

Я думаю, вы неправильно поняли. Каждый ответ имеет только один голос. Голосование по одному из ответов должно проводиться адвокатом, а голосование по другому ответу должно быть у студента. Это показывает консоль. В любом случае, я прошел мимо этой проблемы с ответом Дмитрия, но все еще есть одна небольшая проблема, как объясняется в моем комментарии к его ответу, когда пустой массив внутри массива рассматривается как 1 результат по моей логике представления. – BrainLikeADullPencil

Смежные вопросы