我的用户有以下型号:
class User < ActiveRecord::Base
has_many :facebook_friendships
has_many :facebook_friends, :through => :facebook_friendships, :source => :friend
def mutual_facebook_friends_with(user)
User.find_by_sql ["SELECT users.* FROM facebook_friendships AS a
INNER JOIN facebook_friendships AS b
ON a.user_id = ? AND b.user_id = ? AND a.friend_id = b.friend_id
INNER JOIN users ON users.id = a.friend_id", self.id, user.id]
end
end
class FacebookFriendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => 'User'
end
如果id为53的用户和id为97的用户是彼此的朋友,那么您将在数据库的facebook_friendships表中拥有行[53,57]和[97,53]。这是我用来计算共同朋友的原始SQL查询:
SELECT users.* FROM facebook_friendships AS a
INNER JOIN facebook_friendships AS b
ON a.user_id = :user_a AND b.user_id = :user_b AND a.friend_id = b.friend_id
INNER JOIN users ON users.id = a.friend_id
我会将mutual_friends_with返回一个关系而不是一个数组。通过这种方式,我可以将结果与其他条件(例如where(大学:'NYU'))联系起来,并获得所有ActiveRecord的优点。有没有办法做到这一点?
答案 0 :(得分:0)
您是否尝试过#find_by_sql
?
http://guides.rubyonrails.org/active_record_querying.html#finding-by-sql
如果您想使用自己的SQL来查找表中的记录,则可以 使用find_by_sql。 find_by_sql方法将返回一个数组 即使基础查询只返回单个记录,也会出现对象。对于 例如,您可以运行此查询:
Client.find_by_sql("SELECT * FROM clients INNER JOIN orders ON clients.id = orders.client_id ORDER clients.created_at desc")
find_by_sql为您提供了一种简单的自定义调用方式 数据库和检索实例化对象。
答案 1 :(得分:0)
这是我用来结交共同朋友的方式。
has_many :company_friendships, autosave: true
has_many :company_friends, through: :company_friendships, autosave: true
has_many :inverse_company_friendships, class_name: "CompanyFriendship", foreign_key: "company_friend_id", autosave: true
has_many :inverse_company_friends, through: :inverse_company_friendships, source: :company, autosave: true
def mutual_company_friends
Company.where(id: (company_friends | inverse_company_friends).map(&:id))
end