[RUBY-ON-RAILS] 액티브가 포함되어 있습니다. 포함 된 열을 지정합니다
RUBY-ON-RAILS액티브가 포함되어 있습니다. 포함 된 열을 지정합니다
나는 모델의 프로필을 가지고있다. 프로필 has_one 사용자. 사용자 모델은 필드의 이메일을 가지고있다. 언제 전화
Profile.some_scope.includes(:user)
그것은 호출
SELECT users.* FROM users WHERE users.id IN (some ids)
하지만 내 사용자 모델은 내가 렌더링에 사용하지 오전 많은 분야가 있습니다. 그것은 사용자로부터 만 이메일을로드 할 수 있습니까? 그래서, SQL은 같아야합니다
SELECT users.email FROM users WHERE users.id IN (some ids)
해결법
-
==============================
1.레일 쿼리를 포함에 대한 옵션을 전달하는 기능을 가지고 있겠지. 그러나 우리는 모델에 따라 협회의 선언이 PARAMS를 전달할 수 있습니다.
레일 쿼리를 포함에 대한 옵션을 전달하는 기능을 가지고 있겠지. 그러나 우리는 모델에 따라 협회의 선언이 PARAMS를 전달할 수 있습니다.
이 시나리오의 경우, 프로파일 모델에서 사용자 모델과 새로운 관계를 만들려면 다음과 같이해야합니다
belongs_to :user_only_fetch_email, :select => "users.id, users.email", :class_name => "User"
그냥 하나 더 연결을 생성하지만 사용자 모델 만 가리 킵니다. 당신은 쿼리 할 수 있도록,
Profile.includes(:user_only_fetch_email)
또는
Profile.includes(:user_only_fetch_email).find(some_profile_ids)
-
==============================
2.특정 속성을 선택합니다, 당신은 포함하기보다는 조인 사용해야합니다.
특정 속성을 선택합니다, 당신은 포함하기보다는 조인 사용해야합니다.
이 asciicast에서 :
조인 사용 :
Profile.some_scope.joins(:users).select("users.email")
-
==============================
3.당신은 추가해야 할 모델에 속한다.
당신은 추가해야 할 모델에 속한다.
간단한 협회 :
belongs_to :user_restricted, -> { select(:id, :email) }, class_name: 'User'
다형성 (: commentable 예) 협회 :
belongs_to :commentable_restricted, -> { select(:id, :title) }, polymorphic: true, foreign_type: :commentable_type, foreign_key: :commentable_id
당신은 당신이 원하는 이름을 belongs_to 무엇이든 선택할 수 있습니다. (: user_restricted), Comment.recent.includes (: commentable_restricted 등) 위의 예를 들어, Article.featured.includes처럼 사용할 수 있습니다
-
==============================
4.레일이 포함 된 경우 특정 열을 선택 지원하지 않습니다. 당신은 그냥 게으른 부하의, 알고있다.
레일이 포함 된 경우 특정 열을 선택 지원하지 않습니다. 당신은 그냥 게으른 부하의, 알고있다.
그것은 데이터가 실제로 사용하기 전에 관련 데이터를로드하기 위해 액티브 :: 협회 :: 프리 로더 모듈을 사용합니다. 방법으로 :
def preload(records, associations, preload_scope = nil) records = Array.wrap(records).compact if records.empty? [] else records.uniq! Array.wrap(associations).flat_map { |association| preloaders_on association, records, preload_scope } end end
프리로드의 세 번째 PARAMS을 preload_scope, 열을 지정 선택하는 방법입니다. 그러나 게으른 부하는 더 이상 할 수 없습니다.
relation = Profile.where(id: [1,2,3]) user_columns = {:select=>[:updated_at, :id, :name]} preloader = ActiveRecord::Associations::Preloader.new preloader.preload(relation, :user, user_columns)
그것은 단지 하나의 연관에 대해, 당신은. 그러나 전달 된 지정 열을 선택합니다. 한 번에 지원 로딩 여러 복잡한 협회에 액티브 :: 협회 :: 프리 로더에 대한 패치를 만들 필요가있다.
다음 패치에 대한 예입니다
그것을 사용하는 방법, 예를
-
==============================
5.나 자신, 그래서 그것을 사용하시기 바랍니다 기능을 원했다. 클래스에서이 방법을 포함
나 자신, 그래서 그것을 사용하시기 바랍니다 기능을 원했다. 클래스에서이 방법을 포함
문자열 형식의 #ACCEPTS의 인수 "ASSOCIATION_NAME : COLUMN_NAME-COLUMN_NAME"
def self.includes_with_select(*m) association_arr = [] m.each do |part| parts = part.split(':') association = parts[0].to_sym select_columns = parts[1].split('-') association_macro = (self.reflect_on_association(association).macro) association_arr << association.to_sym class_name = self.reflect_on_association(association).class_name self.send(association_macro, association, -> {select *select_columns}, class_name: "#{class_name.to_sym}") end self.includes(*association_arr) end
그리고 당신처럼 호출 할 수있을 것입니다 : Contract.includes_with_select ( '사용자 : ID-이름 상태', '확인 : 확인-ID'), 그리고 그 지정된 열을 선택합니다.
-
==============================
6.Mohanaj의 예를 사용하여이 작업을 수행 할 수 있습니다 :
Mohanaj의 예를 사용하여이 작업을 수행 할 수 있습니다 :
belongs_to :user_only_fetch_email, -> { select [:id, :email] }, :class_name => "User"
from https://stackoverflow.com/questions/12400860/activerecord-includes-specify-included-columns by cc-by-sa and MIT license
'RUBY-ON-RAILS' 카테고리의 다른 글
[RUBY-ON-RAILS] 어떻게 레일 응용 프로그램에서 경쟁 조건을 피할 수 있습니까? (0) | 2020.03.02 |
---|---|
[RUBY-ON-RAILS] 유효성 수용은 항상 실패 (0) | 2020.03.02 |
[RUBY-ON-RAILS] 정의되지 않은 방법 attr_accessible (0) | 2020.03.02 |
[RUBY-ON-RAILS] 번역이없는 경우 기본 언어로 다시 가을 (0) | 2020.03.02 |
[RUBY-ON-RAILS] Heroku가 - 현재의 디스플레이 해시 커밋 (0) | 2020.03.01 |