레일을 통한 has_one / has_many의 소스 옵션 이해


184

협회 :source옵션을 이해하도록 도와주세요 has_one/has_many :through. Rails API 설명은 제게 이해가되지 않습니다.

"지정 소스 연결 이름으로 사용 has_many :through => :queries. 이름이 협회로부터 추론 할 수없는 경우에만 사용하십시오. has_many :subscribers, :through => :subscriptions중 하나를 찾습니다 :subscribers:subscriberSubscription, A는하지 않는 :source주어집니다."

답변:


238

때로는 다른 연결에 다른 이름을 사용하려고 할 때가 있습니다. 모델의 연관에 사용하려는 이름이 모델의 연관과 동일하지 않은 경우 :through모델 :source을 지정할 수 있습니다.

위의 단락이 문서의 단락 보다 훨씬 명확 하지 않다고 생각 하므로 여기에 예가 있습니다. Pet, Dog및 세 가지 모델이 있다고 가정 해 봅시다 Dog::Breed.

class Pet < ActiveRecord::Base
  has_many :dogs
end

class Dog < ActiveRecord::Base
  belongs_to :pet
  has_many :breeds
end

class Dog::Breed < ActiveRecord::Base
  belongs_to :dog
end

이 경우 우리는 네임 스페이스 Dog::Breed를 사용하기 Dog.find(123).breeds로 결정했습니다.

이제에 대한 has_many :dog_breeds, :through => :dogs연결 을 만들려면 Pet갑자기 문제가 발생합니다. 레일은 찾을 수 없습니다 :dog_breeds에 연결을 Dog레일 가능성이 알 수 있도록 하는 Dog 사용할 협회. 입력 :source:

class Pet < ActiveRecord::Base
  has_many :dogs
  has_many :dog_breeds, :through => :dogs, :source => :breeds
end

:source우린 이야기가 레일, 라는 협회를 찾아 :breedsDog모델 (즉, 사용 모델의로 :dogs그 및 사용).


2
나는 당신이 당신의 마지막 반 동물이 반 애완 동물이라고 부르는 것을 의미한다고 생각합니다.
Kamilski81

3
위의 예에서, 상기 연결은 아래에 있어야 Doghas_many :breed대신 :breeds다음이 :source:breed대신, 모델명 단수 표현하기 위해 :breeds어떤 테이블 이름을 나타내는? 예 has_many :dog_breeds, :through => :dogs, :source => :breed(더 s부기 없다 :breed)?
LazerSharks

1
나는 이것을 테스트했다. 그것은 더 단수없는 s에 접미사:source =>
안와르

"이 경우, Dog :: Breed의 네임 스페이스를 선택했습니다. Dog.find (123) .breeds를 훌륭하고 편리한 연결로 액세스하기 때문입니다." 이를 위해 네임 스페이스가 필요하지 않습니까?
Jwan622

201

이 예를 확장 해 보겠습니다.

class User
  has_many :subscriptions
  has_many :newsletters, :through => :subscriptions
end

class Newsletter
  has_many :subscriptions
  has_many :users, :through => :subscriptions
end

class Subscription
  belongs_to :newsletter
  belongs_to :user
end

이 코드를 사용 Newsletter.find(id).users하면 뉴스 레터 구독자 목록을 얻는 것과 같은 작업을 수행 할 수 있습니다 . 그러나보다 명확하고 Newsletter.find(id).subscribers대신 입력 하려면 뉴스 레터 클래스를 다음과 같이 변경해야합니다.

class Newsletter
  has_many :subscriptions
  has_many :subscribers, :through => :subscriptions, :source => :user
end

의 이름을로 변경하고 users있습니다 subscribers. 을 제공하지 않으면 :sourceRails는 subscriberSubscription 클래스에서 호출 된 연결을 찾습니다 . user구독자 목록을 작성하려면 구독 클래스 의 연관 을 사용하도록 지시해야합니다.


2
단수 모델 이름은 :source =>복수가 아닌로 사용해야합니다 . 그래서, :users틀 렸습니다, :user맞습니다
Anwar

이것이 정답입니다!,이 부분을 강조하겠습니다. "사용자와 가입자의 이름을 바꾸는 중입니다. : source를 제공하지 않으면 Rails는 Subscription 클래스에서 subscriber라는 연결을 찾습니다."
Brian Joseph Spinos

11

가장 간단한 답변 :

중간에있는 테이블의 관계 이름입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.