2

나는 우리가 usersthemes이 레일 4.1.7 응용 프로그램이 있습니다Rails4 재정의 has_many 게터 방법

class User < ActiveRecord::Base 
    has_many :themes 
end 

class Theme < ActiveRecord::Base 
    belongs_to :user 
end 

이제 사용자가 다음 몇 가지 자신의 테마를 (만들 수 있습니다이 테마에 대한 그들의 user_id 세트가됩니다 사용자의 id가) 또는 사전 정의 된 테마 중 하나를 사용할 수 있습니다 (user_id 세트 내가하고 싶은 무엇

) null이다 한 다음 내가 @user.themes를 호출 할 때이 나를 가지고 있도록 어떻게 든 has_many 연결을 변경하기 일 e는 사용자의 테마와 함께 테마를 미리 정의합니다.

내가 시도하는 것 :

1) 대신 has_many 협회의 인스턴스 메서드 정의 : 나는 사용자와 테마를 열망 -로드 싶습니다 이후

class User < ActiveRecord::Base 
    def themes 
    Theme.where user_id: [id, nil] 
    end 
end 

을하지만 (들) (includes(:themes)), 실제로는 그렇지 않습니다.

2) 일부 범위 (has_many :themes, -> { where user_id: nil })를 사용하지만과 같은 mySql 쿼리는 비어있는 값을 반환합니다. 나는 Rails5에서 has_many :themes, -> { or.where user_id: nil } 같은 것으로 할 수 있다고 생각하지만 레일스 버전을 변경하는 것은 지금은 옵션이 아닙니다.

+0

사실 사용자가 지정하지 않은 상태의 'Theme'이 각 사용자 (많은 사용자)에게 속해 있기 때문에 연관을 다시 작성하는 것은 좋지 않은 아이디어라고 생각합니다. 'has_one - has_many' 관계가 아닙니다. 목표 달성을 위해 다른 방법을 사용하는 것이 좋습니다. – Ilya

+0

그래, 그게 내가 지금 사용하고있는거야. 오직, 열심히로드하는 것이 훨씬 더 좋을 것입니다 ... – Misu

답변

-1

내 질문을 게시 때문에, 나는 내 목표를 달성하기 위해 여러 가지를 시도했다. 하나는 재미 있었고, 내가 언급 할 가치가 추측 :

내가 unscope 또는 rewhere를 사용하여 has_many assiciation을 unscope을 시도하고,이 모습 :

has_many :themes, -> user = self { # EDIT: `= self` can even be omitted 
    u_id = user.respond_to?(:id) ? user.id : user.ids 

    unscope(where: :user_id).where(user_id: [u_id, nil]) 
    # or the same but with other syntax: 
    rewhere(user_id: [u_id, nil]) 
} 

내가 @user.themes을 시도, 그것은처럼 일 궁금하고 다음 MySQL의 라인 주었다

SELECT `themes`.* FROM `themes` 
     WHERE ((`themes`.`user_id` = 123 OR `themes`.`user_id` IS NULL)) 

을하지만 (나는 내 ​​연구 결국 시작하는 이유) 내가 열망로드 그것을 시도 할 때, 단순히 쿼리를 unscope을 거부하고, 동일한 오래된 012,320했다라인. 결국

는, 일리아의 코멘트 @는 쿼리에 대한 has_many를 사용하는 한 가지이지만, 다른 많은 망칠 수있는 하나의 위해를 예를 들어 할당하고, 무시 같은 다른 측면을 가지고, this 대답과 함께 저를 설득 소지품. 그는 계속 내 질문에 대답을 거부하기 때문에, 항상 - AndreyDeineko의 응답 @를에 관해서는

def available_themes 
    Theme.where user_id: [id, nil] 
end 

:

그래서 내가 좋은 방법을 유지하기로 결정 만 나는 미래의 혼동을 피하기 위해 그것을 더 구체적인 이름을 준 한번도 물어 보지 못했던 무언가에 답하기 위해, 나는 아직도 그의 방법 (나의 available_themes과 동일한 결과를 가지고 있지만 3 개의 추가 질의를 사용하는)이 더 나은 해결책이되는 이유를 이해하지 못한다.

+0

왜 정확히 downvote? – Misu

1

당신은 그 미리 정의 된 것들과 함께 super (관련 테마를 반환하는) (user_idnil)를 사용할 수 있습니다 :

class User < ActiveRecord::Base 
    def themes 
    Theme.where(id: super.ids + Theme.where(user_id: nil).ids) 
    end 
end 
+0

관계 대신 배열을 반환합니다. – Ilya

+0

@Ilya 좋은 지적, 감사합니다! 편집 됨 –

+0

나는 더 나은 해결책 인'Theme.where (user_id : [id, nil]) '가 왜 3 가지 추가 db 쿼리를 사용하고 같은 결과를 얻으며 열망하지 않는다는 것을 알 수 없다. 어느 쪽이든로드 가능. – Misu