HABTM? Questions, Answers and Votes


#1

Hi there, I’m new to rails and loving it, but I’ve hit a problem that
I’m hoping to find an elegant solution for. I’ve been trawling thru
this list and the wiki, but can’t quite find the last piece to the
problem I’m trying to solve.

I’m trying to setup a simple Polling app, you know, posing questions and
voting on answers. So far i have something (this is trimmed down) like:

class Question < ActiveRecord::Base
has_and_belongs_to_many :answers
has_and_belongs_to_many :votes
belongs_to :person
end

class Answer < ActiveRecord::Base
has_and_belongs_to_many :votes, :join_table => ‘questions_votes’
end

class Vote < ActiveRecord::Base
belongs_to :person
has_and_belongs_to_many :answers, :join_table => ‘questions_votes’
has_and_belongs_to_many :questions, :join_table => ‘questions_votes’
end

With the following associated join table:

CREATE TABLE questions_votes (
question_id INTEGER,
answer_id INTEGER,
vote_id INTEGER
)

The above allows me to perform the following:

q = Question.find_first
a = q.answers.find_first
v = a.votes

But, if i try and go the other way, from a vote back to an answer, or
from and answer back to a question, I am passed back an array. i.e.

v.questions or v.answers or a.questions are all valid.

But what i really want is the singular of the aboves, i know i could use
find_first, but that really shouldn’t be necessary. I understand why
this is happening, due to the HABTM relationship.

I’ve tried using belongs_to in the child classes, which works fine, i.e.

class Answer < ActiveRecord::Base
belongs_to :question
has_and_belongs_to_many :votes, :join_table => ‘questions_votes’
end

But I’m then duplicating the foreign keys, which also doesn’t quite seem
the most elegant approach either. given that the relationship already
exists in the join table. Would i just be better off creating a new
method on the child classes, something like:

class Answer < ActiveRecord::Base
has_and_belongs_to_many :votes, :join_table => ‘questions_votes’

def find_question
self.questions.find_first
end
end

It still seems like a kludge, and that the model isn’t quite
representing that data in an accurate manner.

Can you suggest a better way of achieving the above? I’m probably
missing something really obvious here. Maybe i just need to create a
new
Model for the relationships?

-vince


keys: http://codex.net/gpg.asc

This country, with its institutions, belongs to the people who inhabit
it.
Whenever they shall grow weary of the existing government,
they can exercise their constitutional right of amending it,
or exercise their revolutionary right to overthrow it.
– Abraham Lincoln


#2

Vincent AE Scott wrote:

has_and_belongs_to_many :votes
has_and_belongs_to_many :questions, :join_table => ‘questions_votes’
end

I would have expected an answer to be for (belong to) a single question,
and a vote to be for (belong to) a single answer - in other words, I
would expect one-to-many relationships rather than many-to-many.

Your statements below about the behaviour you want support this.

regards

Justin