0

我有用戶模型,我想創建用戶之間的友誼。我已經實現了這個使用has_and_belongs_to_many單向導軌上的雙向has_and_belongs_to_many

has_and_belongs_to_many :friends, class_name: 'User', foreign_key: :friend_id 

我有表,對這個關聯:

create_table :users_users do |t| 
    t.uuid :user_id, null: false 
    t.uuid :friend_id, null: false 
    t.timestamps 
end 

當我通過user.friends得到朋友,我需要有關聯,其中當前用戶是user_id列或friend_id。我目前的解決方案只返回用戶在friend_id表中的記錄。

我對這種兩種溶液:

  1. 重複的記錄[{USER_ID:1,friend_id:2},{USER_ID:2,friend_id:1}]
  2. 覆蓋user.friends方法和返回我的自定義查詢

這兩種解決方案都不夠優雅。

我已閱讀article,但本文的解決方案非常複雜。

這個問題還有其他的解決方案嗎?我使用的是軌道5

回答

0

首先,我寧願使用該物品的解決方案或一個查詢獲取 所有記錄,而不是這個。

活動記錄的方式來做到這一點是:

  1. 創建has_many關係,而不是HABTM關係
  2. 查詢users_users表中查找匹配user_id=my_user.idfriend_id=my_user.id
  3. 所有記錄拉平結果
  4. unique unique
  5. re從陣列

所以我建議把在用戶模式這種方法移動當前用戶:

def all_friends 
    UserFriend.includes(:user, :friend).where("user_id=? OR friend_id=?", id , id).map {|rel| [rel.user, rel.friend] }.flatten.uniq{|u| u.id}.reject{|u| u.id == self.id} 
end 

UserFriend型號:

class CreateUserFriends < ActiveRecord::Migration[5.0] 
    def change 
    create_table :user_friends do |t| 
     t.belongs_to :user, foreign_key: true 
     t.belongs_to :friend, foreign_key: 'friend_id', class: 'User' 

     t.timestamps 
    end 
    end 
end 
+0

與關聯和範圍相比,方法的缺點是在某些情況下,使用merge和相關機制時難以重用。 –

+0

@ma_il同意。我不是這種技術的粉絲,但它的工作原理。 –

0

不是100%肯定,這將工作,但仍然希望在您需要睡眠之前,先給您嘗試一下; 指定您的關聯的自定義查詢方法:

has_and_belongs_to_many :friends, -> { 
    where("friend_id = :user_id OR user_id = :user_id", user_id: id) 
}, class_name: 'User', foreign_key: friend_id 
+0

它不會工作,因爲rails使用內部聯接來獲取這些記錄,並且此查詢將與原始的一個合併。現在查詢如下所示: 'SELECT COUNT(*)FROM「users」INNER JOIN「users_users」ON「users」。「id」=「users_users」。「user_id」WHERE「users_users」。「friend_id」= $ 1 AND friend_id ='96b232eb-43ea-4eaa-9f47-9eae0516fde2'或user_id ='96b232eb-43ea-4eaa-9f47-9eae0516fde2')[[「friend_id」,「96b232eb-43ea-4eaa-9f47-9eae0516fde2」]]' –

+0

仍然可以通過顯式地將連接表名添加到查詢中進行修復。 –