has_many:through如何仅与两种模型一起使用?

时间:2019-06-10 21:34:02

标签: ruby-on-rails ruby ruby-on-rails-5

仅尝试弄清has_many :through在只有两个模型的情况下的工作方式。我知道有很多答案,但是似乎没有一个例子可以仅使用两个模型,所有其他示例都使用三个以上示例模型。

我想回答的问题是,为什么在rails控制台中,我使用命令a.friendshipsa.friends得到两个完全独立的结果,例如a.friends为什么知道将用户对象还给我?但是a.friendships没有。

#User.rb
class User < ApplicationRecord         
  has_many :friendships
  has_many :friends, through: :friendships
end
#Friendship.rb
class Friendship < ApplicationRecord
    belongs_to :user
    belongs_to :friend, class_name: "User"

end
irb(main):020:0> a = User.first
irb(main):016:0> a.friendships
  Friendship Load (0.1ms)  SELECT  "friendships".* FROM "friendships" WHERE "friendships"."user_id" = ? LIMIT ?  [["user_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Friendship id: 1, user_id: 1, friend_id: 2, created_at: "2019-06-10 20:27:16", updated_at: "2019-06-10 20:31:41">]>
irb(main):020:0> a = User.first
irb(main):019:0> a.friends
  User Load (0.1ms)  SELECT  "users".* FROM "users" INNER JOIN "friendships" ON "users"."id" = "friendships"."friend_id" WHERE "friendships"."user_id" = ? LIMIT ?  [["user_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 2, email: "myemail@gmail.com", created_at: "2019-06-10 20:28:25", updated_at: "2019-06-10 20:28:25">]>

2 个答案:

答案 0 :(得分:3)

在设计数据模型时,有时会发现一个应该与其自身相关的模型。例如,您可能希望将所有员工存储在一个数据库模型中,但是能够跟踪经理和下属之间的关系。这种情况可以用自我加入的关联来建模:

 class Employee < ApplicationRecord
  has_many :subordinates, class_name: "Employee",
                          foreign_key: "manager_id"

  belongs_to :manager, class_name: "Employee"
end

使用此设置,您可以检索@ employee.subordinates和@ employee.manager。

来源:https://guides.rubyonrails.org/association_basics.html#self-joins

答案 1 :(得分:1)

users table
-----------
-id
-...
friendships table
-----------------
- id
- user_id
- friend_id

调用@user.friendships时,目标是在friendships中找到@user。它从friendships表(中间表)中返回对象,该对象将relationshipsusers

之间的users' friends

调用@user.friends时,目标是在friends中找到@user。它是要连接users表和friendships表,其中friendships.user_id = @user.id,然后从这些friend_id记录中获取所有friendships,并找到{{1 }}的users数组中包含id