1

i moved from php to rails3, and i still think it was a good decision! Anyway I have some models:

users
questions
answers
question_id
votes
user_id
answer_id

model for users:

has_many :questions
has_many :votes

model for questions:

belongs_to :user
has_many :answers, :dependent => :destroy
accepts_nested_attributes_for :answers, :reject_if => lambda { |a| a[:text].blank? }, :allow_destroy => true

model for answers:

belongs_to :question
has_many :users, :through => :votes, :dependent => :destroy
has_many :votes

model for votes:

belongs_to :answer
belongs_to :user

Now my question, once a user has voted on an answer, the voting for that user and for that specific question should be closed...

I use devise and cancan for users and authorization in the rest of my project...

In my view it should look something like:

<% unless current_user.question_answered.include? question %>

and then do the script where i render the vote buttons...

In my votes model i have an answer_id and a user_id, i know the current_user.id and the current question.id so if the vote.user_id has the vote.answer_id that is in the current question.id than it shouldn't render my button making script... aarghh but how to put this to work...?

Thanks very much in advance! And best regards, Thijs

fl00r
  • 82,987
  • 33
  • 217
  • 237
Thijs
  • 387
  • 5
  • 20

2 Answers2

2

I would personally go outside of devise and write my own method. I think it's a little cleaner and easier to understand. You'll also guarantee with this method that you are only performing a single fast query to your DB. By asking current_user.questions_answered you are querying the database for all questions that a user has answered, which is potentially a much larger result set than checking if the user has voted on the current question:

class User
  def can_vote_on? question
    !question.answers.joins(:votes).where('votes.user_id = ?', id).exists?
  end
end

You can then adjust your view to:

<% if current_user.can_vote_on?(question) %>
Pan Thomakos
  • 34,082
  • 9
  • 88
  • 85
  • Thank you! I will test it today and let you know, i did the rails 3 tutorial, the one from michael hartl, there they also write a user login model... i thougt devise was good, according to many people, but making an own model should be lighter that's true!! – Thijs Apr 03 '11 at 07:10
  • Hi again, i've made a user controller... but i think i'm doing something wrong...? If i still use devise, where should i place code with the "class User"? Thanks! – Thijs Apr 03 '11 at 08:24
  • You should put the code in the User model not in the controller. – tommasop Apr 03 '11 at 16:03
  • @tommasop, that's correct. The code should go in your User model definition (app/models/user.rb). – Pan Thomakos Apr 03 '11 at 17:00
  • Thanks! I've put it in the app/models/user.rb, but when i paste the if statement in the view app/views/questions/show.html.erb it raises NameError in Questions#show: undefined local variable or method `question' for #<#:0xb2f2e9c> Sorry i'm still very nooby here... – Thijs Apr 03 '11 at 17:09
  • You need to replace 'question' with the variable containing the question you want to check. In your original post you used the question variable to refer to the question you wanted to check if the user had voted on. Use the same variable here. Maybe it's @question instead of just question? That part is up to you to decide. – Pan Thomakos Apr 03 '11 at 20:24
  • OK thanks, i will try!! I watched episode 12 from railstutorial from michael hartl again, and now i finally understand, that the code has to be in model! Thanks again also to "tommasop"! Regards, Thijs – Thijs Apr 04 '11 at 07:33
1

in ability write something like this

can :vote, Answer, :votes => { :users => user }

in your view do something like

<% if can? :vote, Answer %>

(i cant really test it right now so let me know if it works)

Andrei S
  • 6,486
  • 5
  • 37
  • 54
  • It wasn't cancan because it was on the user itself, and not about other users... Thanks anyway!! – Thijs Apr 04 '11 at 11:26