0

사용자 모델이 있고 사용자간에 우정을 만들고 싶습니다. 나는이 사용 has_and_belongs_to_many레일의 단일 모델에서 양방향 방향성 has_and_belongs_to_many

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

을 달성했습니다 그리고 난이 연관에 대해 테이블이 : 나는 user.friends를 통해 친구를 얻을 때 현재 사용자가 user_id를 열 또는에 어디 연결이 필요

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

friend_id. 내 현재 솔루션은 사용자가 friend_id 테이블에있는 레코드 만 반환합니다.

  1. 중복 레코드 :

    난이 두 용액에 [{2 friend_id : USER_ID 1}, {2 USER_ID : 1 friend_id}]

  2. 무시 user.friends 방법 및 반환 내 사용자 검색어

두 가지 해결책 모두 우아하고 최적화되지 않았습니다.

article을 읽었지만이 기사의 해결책은 매우 복잡합니다.

이 문제에 대한 다른 해결책이 있습니까? 난 레일 5를 사용하고있다.

답변

0

우선,이 기사 솔루션이나 하나의 쿼리를 사용하여이 대신 모든 레코드 을 가져온다.

이 작업을 수행하는 활성 기록 방법은 다음과 같습니다

  1. 이 결과를 평평하게 user_id=my_user.id 또는 friend_id=my_user.id
  2. 일치하는 모든 레코드를 찾을 수 has_many 관계 대신 HABTM 관계
  3. 쿼리 users_users 테이블을 만들
  4. 개 고유 번호

그래서 난 사용자 모델에서이 방법을 넣어 제안 배열에서 현재 사용자를 이동 :

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

연관성 및 범위와는 달리 메소드의 단점은 특정 상황에서 '병합'및 관련 메커니즘을 사용할 때 재사용하기가 어렵다는 것입니다. –

+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

레일즈가이 레코드를 가져 오기 위해 내부 조인을 사용하고이 쿼리가 원래의 레코드와 병합되기 때문에 작동하지 않습니다 ..이제 쿼리는 다음과 같이 보입니다 : '사용자로부터 SELECT COUNT (*) "사용자"INNER JOIN "users_users"ON "사용자". "id"= "users_users". "user_id"WHERE "users_users". "friend_id"= $ 1 AND 친구 ID = '96b232eb-43ea-4eaa-9f47-9eae0516fde2'OR user_id = '96b232eb-43ea-4eaa-9f47-9eae0516fde2') [[ "friend_id", "96b232eb-43ea-4eaa-9f47-9eae0516fde2"]] ' –

+0

글쎄 명시 적으로 조인 테이블 이름을 쿼리에 추가하여 여전히 해결할 수 있습니다. –