[ruby-on-rails] 협회를 통한 belongs_to

다음과 같은 연관성을 고려할 때 Questiona ChoiceChoice모델 에서 연결되어 있음 을 참조해야합니다 . belongs_to :question, through: :answer이 작업을 수행하는 데 사용하려고했습니다 .

class User
  has_many :questions
  has_many :choices
end

class Question
  belongs_to :user
  has_many :answers
  has_one :choice, :through => :answer
end

class Answer
  belongs_to :question
end

class Choice
  belongs_to :user
  belongs_to :answer
  belongs_to :question, :through => :answer

  validates_uniqueness_of :answer_id, :scope => [ :question_id, :user_id ]
end

나는 얻고있다

NameError 초기화되지 않은 상수 User::Choice

내가 할 때 current_user.choices

내가 포함하지 않으면 잘 작동합니다.

belongs_to :question, :through => :answer

그러나 나는 그것을 할 수 있기를 원하기 때문에 그것을 사용하고 싶습니다. validates_uniqueness_of

아마도 간단한 것을 간과하고있을 것입니다. 도움을 주시면 감사하겠습니다.



답변

belongs_to협회는 할 수 없습니다 :through옵션을 선택합니다. 당신은 캐싱 더 낫다 question_idChoice테이블에 고유 인덱스를 추가 (특히 때문에이 validates_uniqueness_of경쟁 조건하는 경향이있다).

편집증 환자라면 Choice답변의 question_id일치 여부 를 확인 하는 사용자 지정 유효성 검사를 추가 하지만 최종 사용자에게 이러한 종류의 불일치를 생성하는 데이터를 제출할 기회가 주어지지 않는 것처럼 들립니다.


답변

다음을 위임 할 수도 있습니다.

class Company < ActiveRecord::Base
  has_many :employees
  has_many :dogs, :through => :employees
end

class Employee < ActiveRescord::Base
  belongs_to :company
  has_many :dogs
end

class Dog < ActiveRecord::Base
  belongs_to :employee

  delegate :company, :to => :employee, :allow_nil => true
end


답변

다음 과 같이 has_one대신 대신 사용 하십시오.belongs_to:through

class Choice
  belongs_to :user
  belongs_to :answer
  has_one :question, :through => :answer
end

관련이 없지만 데이터베이스에서 적절한 고유 제약 조건을 사용하는 대신 validates_uniqueness_of를 사용하는 것이 주저합니다. 루비에서이 작업을 수행하면 경쟁 조건이 있습니다.


답변

내 접근법은 데이터베이스 열을 추가하는 대신 가상 속성을 만드는 것이 었습니다.

class Choice
  belongs_to :user
  belongs_to :answer

  # ------- Helpers -------
  def question
    answer.question
  end

  # extra sugar
  def question_id
    answer.question_id
  end
end

이 방법은 매우 간단하지만 단점이 있습니다. answerDB에서 Rails를로드 한 다음에 로드해야합니다 question. 나중에 필요한 연결을 열망하여 나중에 최적화 할 수 c = Choice.first(include: {answer: :question})있지만,이 최적화가 필요한 경우 stephencelis의 답변이 더 나은 성능 결정일 것입니다.

특정 선택을위한 시간과 장소가 있으며, 프로토 타입을 만들 때이 선택이 더 낫다고 생각합니다. 자주 사용하지 않는 경우가 아니라면 프로덕션 코드에 사용하지 않습니다.


답변

질문이 많은 사용자가 원하는 것 같습니다.
질문에는 많은 답변이 있으며 그중 하나가 사용자의 선택입니다.

이것이 당신이 무엇을하고 있습니까?

이 라인을 따라 이와 같은 것을 모델링합니다.

class User
  has_many :questions
end

class Question
  belongs_to :user
  has_many   :answers
  has_one    :choice, :class_name => "Answer"

  validates_inclusion_of :choice, :in => lambda { answers }
end

class Answer
  belongs_to :question
end


답변

그래서 당신은 당신이 원하는 행동을 할 수 없지만 당신은 그것과 같은 느낌을 줄 수 있습니다. 당신은 할 수 있기를 원합니다Choice.first.question

내가 과거에 한 일은 다음과 같습니다

class Choice
  belongs_to :user
  belongs_to :answer
  validates_uniqueness_of :answer_id, :scope => [ :question_id, :user_id ]
  ...
  def question
    answer.question
  end
end

이 방법으로 당신은 지금 선택에 대한 질문을 할 수 있습니다


답변

이 아닌 has_many :choices이라는 이름의 연결을 만듭니다 . 대신 사용해보십시오 .choiceschoicecurrent_user.choices

마법 에 대한 정보 는 ActiveRecord :: Associations 문서를 참조하십시오 has_many.