Ruby-on-Rails : 다중 has_many : through 가능?
has_many :through
Rails에서 서로를 통과하는 여러 관계 를 가질 수 있습니까? 게시 한 다른 질문에 대한 해결책으로 그렇게하라는 제안을 받았지만 제대로 작동하지 못했습니다.
친구는 조인 테이블을 통한 순환 연결 입니다. 목표는 has_many :through
for 를 만드는 friends_comments
것이므로 a 를 가져 와서 친구의 모든 댓글을 단일 쿼리로 가져 오는 User
것과 같은 작업을 수행 할 수 있습니다 user.friends_comments
.
class User
has_many :friendships
has_many :friends,
:through => :friendships,
:conditions => "status = #{Friendship::FULL}"
has_many :comments
has_many :friends_comments, :through => :friends, :source => :comments
end
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
end
이것은 멋지고 말이되지만 나를 위해 작동하지 않습니다. 이것은 사용자의 friends_comments에 액세스하려고 할 때 관련 부분에서 발생하는 오류입니다.
ERROR: column users.user_id does not exist
: SELECT "comments".* FROM "comments" INNER JOIN "users" ON "comments".user_id = "users".id WHERE (("users".user_id = 1) AND ((status = 2)))
작동하는 user.friends를 입력하면 다음과 같은 쿼리가 실행됩니다.
: SELECT "users".* FROM "users" INNER JOIN "friendships" ON "users".id = "friendships".friend_id WHERE (("friendships".user_id = 1) AND ((status = 2)))
그래서 has_many
우정 관계를 통해 원본 을 완전히 잊은 것 같고 , 부적절하게 User 클래스를 조인 테이블로 사용하려는 것 같습니다.
내가 뭔가를 잘못하고 있습니까, 아니면 이것이 단순히 불가능합니까?
편집하다:
Rails 3.1은 중첩 된 연결을 지원합니다. 예 :
has_many :tasks
has_many :assigments, :through => :tasks
has_many :users, :through => :assignments
아래에 주어진 솔루션이 필요하지 않습니다. 자세한 내용은 이 스크린 캐스트를 참조하십시오.
원래 답변
has_many :through
다른 has_many :through
연결 의 소스로 연결을 전달하고 있습니다. 나는 그것이 작동 할 것이라고 생각하지 않는다.
has_many :friends,
:through => :friendships,
:conditions => "status = #{Friendship::FULL}"
has_many :friends_comments, :through => :friends, :source => :comments
이 문제를 해결하기위한 세 가지 접근 방식이 있습니다.
1) 연관 확장 작성
has_many :friends,
:through => :friendships,
:conditions => "status = #{Friendship::FULL}" do
def comments(reload=false)
@comments = nil if reload
@comments ||=Comment.find_all_by_user_id(map(&:id))
end
end
이제 다음과 같이 친구 댓글을받을 수 있습니다.
user.friends.comments
2) User
클래스에 메서드를 추가합니다 .
def friends_comments(reload=false)
@friends_comments = nil if reload
@friends_comments ||=Comment.find_all_by_user_id(self.friend_ids)
end
이제 다음과 같이 친구 댓글을받을 수 있습니다.
user.friends_comments
3) 이것이 훨씬 더 효율적 이길 원한다면 :
def friends_comments(reload=false)
@friends_comments = nil if reload
@friends_comments ||=Comment.all(
:joins => "JOIN (SELECT friend_id AS user_id
FROM friendships
WHERE user_id = #{self.id}
) AS friends ON comments.user_id = friends.user_id")
end
이제 다음과 같이 친구 댓글을받을 수 있습니다.
user.friends_comments
All methods cache the results. If you want to reload the results do the following:
user.friends_comments(true)
user.friends.comments(true)
OR better still:
user.friends_comments(:reload)
user.friends.comments(:reload)
There is a plugin that solves your problem, take a look at this blog.
You install the plugin with
script/plugin install git://github.com/ianwhite/nested_has_many_through.git
Although this didn't work in the past, it works fine in Rails 3.1 now.
I found this blog entry to be useful: http://geoff.evason.name/2010/04/23/nested-has_many-through-in-rails-or-how-to-do-a-3-table-join/
ReferenceURL : https://stackoverflow.com/questions/2383479/ruby-on-rails-multiple-has-many-through-possible
'programing' 카테고리의 다른 글
Firefox 및 Chrome은 localhost에서 느립니다. (0) | 2021.01.14 |
---|---|
.NET에서 프로그래밍 방식으로 현재 프로세스의 총 메모리 사용량을 측정하는 방법은 무엇입니까? (0) | 2021.01.14 |
"활성화 / 비활성화"라는 단어는 무엇입니까? (0) | 2021.01.14 |
belongs_to 다형성과 함께 accepts_nested_attributes_for (0) | 2021.01.14 |
Java에서 확인되지 않은 호출 경고를 수정하는 방법은 무엇입니까? (0) | 2021.01.14 |