【发布时间】:2014-03-09 11:17:53
【问题描述】:
我在通过Friendship 模型定义的User 模型之间有关系。 (ROR 4)
用户
class User < ActiveRecord::Base
has_many :friendships, ->(object) { where('user_id = :id OR friend_id = :id', id: object.id) }
has_many :friends, ->(object) { where(friendships: {status: 'accepted'}).where('user_id = :id OR friend_id = :id', id: object.id) }, through: :friendships, source: :friend
has_many :requested_friends, -> { where(friendships: {status: 'pending'}) }, through: :friendships, source: :friend
end
友谊
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, class_name: 'User'
def self.request(user, friend)
unless user == friend or find_friendship(user, friend) != nil
create(user: user, friend: friend, status: 'pending')
end
end
def self.find_friendship(user, friend)
ids = [user.id, friend.id]
where(user_id: ids, friend_id: ids).first
end
end
但是,这不起作用,并且由于产生了 SQL 查询,我的测试失败了。
友谊关系
> user.friendships
查询:
SELECT "friendships".* FROM "friendships"
WHERE "friendships"."user_id" = ?
AND (user_id = 1 OR friend_id = 1) [["user_id", 1]]
所以 AND 之前的 WHERE 的一部分“杀死”了我的实际位置。我通过制作实例方法做了一个解决方法:
def friendships
self.class
.select('friendships.* FROM `friendships`')
.where('user_id = :id OR friend_id = :id', id)
end
有没有办法可以删除我的实例方法并修改 has_many 关系以生成我想要的 SQL?
Requested_friends 关系
> Friendship.request(user, friend)
> friend.requested_friends
查询:
SELECT "users".* FROM "users"
INNER JOIN "friendships" ON "users"."id" = "friendships"."friend_id"
WHERE "friendships"."status" = 'pending'
AND "friendships"."user_id" = ?
AND (user_id = 2 OR friend_id = 2) [["user_id", 2]]
这显然不是我需要的,所以我通过删除 has_many :requested_friends 并创建一个实例方法来解决问题:
def requested_friends
self.class
.joins('JOIN `friendships` friendships ON users.id = friendships.user_id')
.where('friendships.status = ?', 'pending')
.where('friendships.friend_id = ?', id)
end
有什么方法可以修改我的has_many :requested_friends 关系以生成与我的实例方法相同的 SQL?
【问题讨论】:
-
失败的测试是什么样的?
标签: sql ruby-on-rails