:has_many :通过关联而无需约定名称?
create_table "friendships", :force => true do |t|
t.integer "user_id"
t.integer "friend_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "likes", :force => true do |t|
t.string "name"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
这些是
class User < ActiveRecord::Base
has_many :friendships
has_many :friends, :through => :friendships
has_many :likes
has_many :friends_likes, :through => :friendships, :source => :likes
end
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
has_many :likes, :foreign_key => :user_id,
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :friendship
end
我试图获得“朋友的喜欢”的模型,但我做不到。
“User.find(1).friends_likes”给出了该sql查询
SELECT "likes".* FROM "likes" INNER JOIN "friendships" ON "likes".user_id = "friendships".id WHERE (("friendships".user_id = 1))
,但我认为必须是“INNER JOIN“friendships”ON“likes”.user_id =“friendships”。friend_id”
我怎么能这样做吗? 谢谢
create_table "friendships", :force => true do |t|
t.integer "user_id"
t.integer "friend_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "likes", :force => true do |t|
t.string "name"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
And these are the models
class User < ActiveRecord::Base
has_many :friendships
has_many :friends, :through => :friendships
has_many :likes
has_many :friends_likes, :through => :friendships, :source => :likes
end
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
has_many :likes, :foreign_key => :user_id,
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :friendship
end
I'm trying to get "likes of friends" but i can't.
"User.find(1).friends_likes" gives that sql query
SELECT "likes".* FROM "likes" INNER JOIN "friendships" ON "likes".user_id = "friendships".id WHERE (("friendships".user_id = 1))
but i think that has to be "INNER JOIN "friendships" ON "likes".user_id = "friendships".friend_id"
how can i do that?
thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最简单的解决方案可能是在
User
模型上添加一个实例方法friends_likes
来构造正确的 SQL:.includes(:likes)
是为了性能,避免N+1查询的情况。那么您的
User.find(1).friends_likes
将生成以下查询,假设用户 1 有 ID 为 2 和 3 的朋友:如果您确实需要一个查询中的所有内容,您可以直接编写 SQL :
它不是更简单的原因是因为一个用户“拥有”友谊 - 这是单向的,并且似乎没有一种方法可以获得与“朋友”关联的友谊(由
指定)好友表上的friend_id
)。因此,添加相反的方向会有所帮助(除了奇怪的命名):
然后,您可以更简单地查询您要查找的内容:
这将生成与 find_by_sql 基本相同的 SQL例子。
The simplest solution is probably to add an instance method
friends_likes
on theUser
model that constructs the correct SQL:The
.includes(:likes)
is for performance, to avoid an N+1 query situation.Then your
User.find(1).friends_likes
will produce the following queries, assuming user 1 has friends with ids 2 and 3:If you really need everything in one query, you could write straight-up SQL:
The reason it isn't more straightforward is because one User "owns" the friendship - it's one-way, and there doesn't seem to be a way to get the Friendships associated with the "Friend" (specified by
friend_id
on the friendships table).So, adding that opposite direction will help (weird naming aside):
Then, you can query for the thing you're looking for a bit more simply:
That'll generate essentially the same SQL as the
find_by_sql
example.