问题
I'm having real trouble pulling out a set of records that are self-referentially related to a user in order to show these on a user's 'show' page.
Here's the idea:
Users (current_user
) rate the compatibility between two other users (user_a
and user_b
). They can rate compatibility either positively or negatively: rating two users "compatible" creates a positive_connection
between user_a and user_b, and rating them "incompatible" creates a negative_connection
. So there are models for positive_connection, negative_connection and user.
Now I need to display only users that are overall_positively_connected_to(@user)
(i.e. where positive_connections_to(@user).count > negative_connections_to(@user).count)
.
This is where I've got to, but I can't get any further:
User model:
def overall_positive_connected_to(user)
positive_connections_to(user).count > negative_connections_to(user).count
end
def positive_connections_to(user)
positive_connections.where("user_b_id = ?", user)
end
def negative_connections_to(user)
negative_connections.where("user_b_id = ?", user)
end
Controller
@user.user_bs.each do |user_b|
if user_b.overall_pos_connected_to(@user)
@compatibles = user_b
end
end
The code in the controller is clearly wrong, but how should I go about doing this? I'm completely new to rails (and sql), so may have done something naive.
Any help would be great.
回答1:
So am I right in saying you have 3 models
- User (id, name)
- PositiveConnection (user_a_id, user_b_id)
- NegativeConnection (user_a_id, user_b_id)
Or something of that sort.
I think you just want 2 models and for convenience I'm going to rename the relations as "from_user" and "to_user"
- User (id, name)
- Connection (value:integer, from_user_id, to_user_id)
Where value is -1 for a negative and +1 for a positive.
Now we can have do something like (note: you need to sort out the exact syntax, like :foreign_key, and :source, and stuff)
class User
has_many :connections, :foreign_key => "from_user_id"
has_many :connected_users, :through => :connections, :source => :to_user
def positive_connections
connections.where(:value => 1)
end
def negative_connections
...
end
end
But we also now have a framework to create a complex sql query (again you need to fill in the blanks... but something like)
class User
def positive_connected_users
connected_users.joins(:connections).group("from_user_id").having("SUM(connections.value) > 0")
end
end
this isn't quite going to work but is kind of pseudo code for a real solution
(it might be better to think in pure sql terms)
SELECT users.* FROM users
INNER JOIN connections ON to_user_id = users.id
WHERE from_user_id = #{user.id}
HAVING SUM(connections.value) > 0
来源:https://stackoverflow.com/questions/6314135/self-referential-find-in-controller-count-relations