ruby on rails - entry returned on first query, empty on second -
i have application allows lawyers , law students answer legal questions. answers can voted up. beside each answer on views/question/show.html.erb, application indicates whether answer has been voted , (a lawyer, or law student). however, it's behaving oddly. currently, on test question, if lawyer votes answer, application not showing upvote, if student votes answer, both student's , lawyer's vote displayed, both displayed student votes.
this code in show action of questions controller retrieves answers question, , queries type of votes each answer has.
def show @question = question.find(params[:id]) @answers = @question.answers @answers.each |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
if in console puts statements, shows @lawyervotes contains 1 result, it's empty array. currently, there 2 answers question, why puts statement run twice, don't know why it's empty on second time through
[#<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
note, reason why put reload
on end of each query avoid activerecord::associationtypemismatch error getting, according answer found can happen when query 'where.' found answer said putting 'reload' on end of where
query can avoid error.
can explain why odd behavior might happening lawyervotes , student votes , possibly tell me how rewrite show action avoid it. thank in advance.
update
this console record showing question 62 has 2 answers, each 1 answer_vote. 1 of answer votes lawyer (lawyer = true) while 1 student (student = true), however, they're both showing student votes in application, after trying dmitry's solution.
>> q = question.find_by_id(62) question load (0.2ms) select "questions".* "questions" "questions"."id" = 62 limit 1 => #<question id: 62, details: "i have terminal illness don't have time go...", question: "what happens if die without 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".* "answers" "answers"."question_id" = 62 => [#<answer id: 54, content: "there legislation determines 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 detail 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".* "answers" "answers"."id" = 54 limit 1 => #<answer id: 54, content: "there legislation determines 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".* "answer_votes" "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".* "answers" "answers"."id" = 55 limit 1 => #<answer id: 55, content: "ontario has statutory provisions detail 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".* "answer_votes" "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
i put code in loop
puts answervote.where({:answer_id => a.id}).reload.inspect puts "inspectinganswervote"
and got result
[#<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 author of answer" if answer.user_id == user_id end end
one of problems -- rewrite @lawyervotes array during next iteration. 1 of ways out append instead (using like:
@lawyervotes = [] @answers.each |a| @lawyervotes <<= answervote.where({:answer_id => a.id, :lawyervote => true}).reload ... end
but super-terrible, non-rails style. mentioned above, do not need iteration through @answers, write:
updated
@lawyervotes = @question.answers.map {|a| a.answer_votes.lawyers}.reject!(&:empty?).flatten @studentvotes = @question.answers.map {|a| a.answer_votes.students}.reject!(&:empty?).flatten
and in answervotes model:
scope :lawyers, where(lawyervote: true) scope :students, where(studentvote: true)
Comments
Post a Comment