[RUBY-ON-RAILS] 다형성 협회는 같은 모델의 여러 단체와 레일
RUBY-ON-RAILS다형성 협회는 같은 모델의 여러 단체와 레일
내 질문은 기본적으로 이것과 동일합니다 : 같은 모델의 여러 단체와 다형성 협회
그러나, 제안 / 접수 솔루션은 나중에 주석에 의해 그림과 같이하지 작업을 수행합니다.
내 모든 응용 프로그램에 걸쳐 사용되는 사진 클래스가 있습니다. 게시물은 하나의 사진을 가질 수 있습니다. 그러나, 나는 두 번째 사진을 추가 할 수 다형성의 관계를 다시 사용하려고합니다.
전에:
class Photo
belongs_to :attachable, :polymorphic => true
end
class Post
has_one :photo, :as => :attachable, :dependent => :destroy
end
원하는 :
class Photo
belongs_to :attachable, :polymorphic => true
end
class Post
has_one :photo, :as => :attachable, :dependent => :destroy
has_one :secondary_photo, :as => :attachable, :dependent => :destroy
end
그러나,이는 클래스 "SecondaryPhoto"를 찾을 수 없습니다로 실패합니다. 내가 다른 스레드에서 말할 수있는 무엇을 바탕으로, 내가하고 싶은 것 :
has_one :secondary_photo, :as => :attachable, :class_name => "Photo", :dependent => :destroy
우편 번호의 secondary_photo를 호출하는 경우를 제외하고 단순히 사진 협회, 예를 통해 연결되어 같은 사진을 반환 포스트 # 사진 === 우편 번호의 secondary_photo. 유형 = "SecondaryPhoto"대신 말의 "사진", 내가 원하는만큼 어디 SQL을 보면, 그렇습니다 ...
생각? 감사!
해결법
-
==============================
1.나는 내 프로젝트에서 그 일을했다.
나는 내 프로젝트에서 그 일을했다.
트릭은 사진 기본 및 보조 사진을 구별하는 has_one 조건에 사용되는 열을 필요로한다는 것입니다. 여기 조건 :에 무슨 일에주의하십시오.
has_one :photo, :as => 'attachable', :conditions => {:photo_type => 'primary_photo'}, :dependent => :destroy has_one :secondary_photo, :class_name => 'Photo', :as => 'attachable', :conditions => {:photo_type => 'secondary_photo'}, :dependent => :destroy
이 방법의 장점은 당신이 post.build_photo @ 사용하여 사진을 만들 때 photo_type가 자동으로 'primary_photo'와 같은 형식을 해당가 미리 입력되어있을 것입니다. 액티브는 작업을 수행하는 스마트 충분하다.
-
==============================
2.4.2 레일
4.2 레일
class Photo belongs_to :attachable, :polymorphic => true end class Post has_one :photo, :as => :attachable, :dependent => :destroy has_one :secondary_photo, -> { where attachable_type: "SecondaryPhoto"}, class_name: Photo, foreign_key: :attachable_id, foreign_type: :attachable_type, dependent: :destroy end
당신은 따라 foreign_key 제공해야합니다 .... able'ness 또는 레일 사진을 테이블에 post_id를 열 요청합니다. SecondaryPhoto으로 레일의 마법 Attachable_type 열 것이다 채우기
-
==============================
3.이전 답변 없음 나는이에이 여기에 넣다 다른 사람 실행을 놓을 게요 그래서 내가이 문제를 해결 도움이되지 않습니다. 레일 4.2 +를 사용.
이전 답변 없음 나는이에이 여기에 넣다 다른 사람 실행을 놓을 게요 그래서 내가이 문제를 해결 도움이되지 않습니다. 레일 4.2 +를 사용.
마이그레이션 만들기 (이미 주소 테이블이 가정) :
class AddPolymorphicColumnsToAddress < ActiveRecord::Migration def change add_column :addresses, :addressable_type, :string, index: true add_column :addresses, :addressable_id, :integer, index: true add_column :addresses, :addressable_scope, :string, index: true end end
설정 당신의 다형성 연관 :
class Address < ActiveRecord::Base belongs_to :addressable, polymorphic: true end
설정 협회가 호출 될 클래스 :
class Order < ActiveRecord::Base has_one :bill_address, -> { where(addressable_scope: :bill_address) }, as: :addressable, class_name: "Address", dependent: :destroy accepts_nested_attributes_for :bill_address, allow_destroy: true has_one :ship_address, -> { where(addressable_scope: :ship_address) }, as: :addressable, class_name: "Address", dependent: :destroy accepts_nested_attributes_for :ship_address, allow_destroy: true end
트릭은 당신이 주문 인스턴스 또는 범위 열에 빌드 방법 채워지지 않습니다 전화를해야한다는 것입니다.
문제가 해결되지 않습니다 그래서 :
address = {attr1: "value"... etc...} order = Order.new(bill_address: address) order.save!
그러나,이 작업을 수행합니다.
address = {attr1: "value"... etc...} order = Order.new order.build_bill_address(address) order.save!
다른 사람에게 도움이되기를 바랍니다.
-
==============================
4.이 게시물을 확인하는 사람들을위한 미래 참조
이 게시물을 확인하는 사람들을위한 미래 참조
이는 다음 코드를 사용하여 달성 할 수 있습니다 ...
3 레일 :
has_one :banner_image, conditions: { attachable_type: 'ThemeBannerAttachment' }, class_name: 'Attachment', foreign_key: 'attachable_id', dependent: :destroy
4 레일 :
has_one :banner_image, -> { where attachable_type: 'ThemeBannerAttachment'}, class_name: 'Attachment', dependent: :destroy
확실하지 왜,하지만 레일 3, 당신은 조건 class_name에 나란히 foreign_key 값을 제공해야합니다. 다형성 유형을 설정할 때 자동으로 호출 클래스 이름을 사용하는이 같은 '부착 :로'사용하지 마십시오.
위의 너무 has_many에 적용됩니다.
-
==============================
5.같은 뭔가 질의에 근무하지만 주소로 사용자로부터 할당하는 일을하지 않았다 다음
같은 뭔가 질의에 근무하지만 주소로 사용자로부터 할당하는 일을하지 않았다 다음
사용자 클래스
has_many :addresses, as: :address_holder has_many :delivery_addresses, -> { where :address_holder_type => "UserDelivery" }, class_name: "Address", foreign_key: "address_holder_id"
주소 클래스
belongs_to :address_holder, polymorphic: true
-
==============================
6.나는 그것을 사용하지 않은,하지만 난 주위를 봤와 레일 소스로 보면서 나는 당신이 찾고있는 것은이라고 생각 : foreign_type. 그것을 시도하고 작동하는지 알 :)
나는 그것을 사용하지 않은,하지만 난 주위를 봤와 레일 소스로 보면서 나는 당신이 찾고있는 것은이라고 생각 : foreign_type. 그것을 시도하고 작동하는지 알 :)
has_one :secondary_photo, :as => :attachable, :class_name => "Photo", :dependent => :destroy, :foreign_type => 'SecondaryPost'
나는 당신의 문제 유형이 각각 포스트 모델에 할당 한 SecondaryPost을 사용하는 것이 좋을 것이다, 포스트 대신에 사진하고한다고 생각합니다.
편집하다:
위의 대답은 완전히 잘못된 것입니다. : foreign_type은 관련 모델 형을 포함하는 컬럼의 이름을 지정 belongs_to 협회에서 다형성 모델에서 사용할 수있다.
나는 레일 소스에 보면,이 라인은 연결이 유형을 설정합니다 :
dependent_conditions << "#{reflection.options[:as]}_type = '#{base_class.name}'" if reflection.options[:as]
당신이 볼 수 있듯이 그것은 유형 이름을 얻을 수 base_class.name 사용합니다. 내가 아는 한 당신은 그것으로 아무것도 할 수 있습니다.
그래서 내 sugestion 예에서, 사진 모델로 하나의 열을 추가하는 것입니다 photo_type. 그리고이 제 사진 인 경우 0으로 설정하거나, 제 2 광이 경우, 1로 설정. 당신의 협회가 추가에서 : 조건 => {: photo_type => 0}과 : 조건 => {: photo_type => 1} 각각. 나는 당신이 찾고있는 솔루션 아니라는 것을 알고,하지만 난 더 아무것도 찾을 수 없습니다. 그런데, 어쩌면 그냥 사용 has_many 협회에 좋을 것이다?
-
==============================
7.당신은 원숭이 패치 has_one 관계에 foreign_type의 개념을해야 할 것. 이것은 내가 has_many 위해 한 것입니다. 당신의 이니셜 새로운 .rb 파일에서 내가 내 add_foreign_type_support.rb라는 폴더 그것은 당신이 당신의 attachable_type 될 것입니다 무엇을 지정할 수 있습니다. 예 : has_many 사진, : class_name을 => "사진", :로 => 부착 : foreign_type => '그림'
당신은 원숭이 패치 has_one 관계에 foreign_type의 개념을해야 할 것. 이것은 내가 has_many 위해 한 것입니다. 당신의 이니셜 새로운 .rb 파일에서 내가 내 add_foreign_type_support.rb라는 폴더 그것은 당신이 당신의 attachable_type 될 것입니다 무엇을 지정할 수 있습니다. 예 : has_many 사진, : class_name을 => "사진", :로 => 부착 : foreign_type => '그림'
module ActiveRecord module Associations class HasManyAssociation < AssociationCollection #:nodoc: protected def construct_sql case when @reflection.options[:finder_sql] @finder_sql = interpolate_sql(@reflection.options[:finder_sql]) when @reflection.options[:as] resource_type = @reflection.options[:foreign_type].to_s.camelize || @owner.class.base_class.name.to_s @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " @finder_sql += "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(resource_type)}" else @finder_sql += ")" end @finder_sql << " AND (#{conditions})" if conditions else @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}" @finder_sql << " AND (#{conditions})" if conditions end if @reflection.options[:counter_sql] @counter_sql = interpolate_sql(@reflection.options[:counter_sql]) elsif @reflection.options[:finder_sql] # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */ @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" } @counter_sql = interpolate_sql(@reflection.options[:counter_sql]) else @counter_sql = @finder_sql end end end end end # Add foreign_type to options list module ActiveRecord module Associations # :nodoc: module ClassMethods private mattr_accessor :valid_keys_for_has_many_association @@valid_keys_for_has_many_association = [ :class_name, :table_name, :foreign_key, :primary_key, :dependent, :select, :conditions, :include, :order, :group, :having, :limit, :offset, :as, :foreign_type, :through, :source, :source_type, :uniq, :finder_sql, :counter_sql, :before_add, :after_add, :before_remove, :after_remove, :extend, :readonly, :validate, :inverse_of ] end end
-
==============================
8.이 문제를 발견 한 후 힘든 시간을했지만 멋진 솔루션 작품이있어
이 문제를 발견 한 후 힘든 시간을했지만 멋진 솔루션 작품이있어
당신의 Gemfile에 추가
그리고이 마법처럼 작동합니다 :
class Resource has_one :icon, as: :assetable, class_name: 'Asset', dependent: :destroy, autosave: true has_one :preview, as: :assetable, class_name: 'Asset', dependent: :destroy, autosave: true end
-
==============================
9.이러한 솔루션 중 어느 것도이 변경되었습니다 협회 조건 주위의 행동처럼 보인다, 어떤 이유로 레일 5. 제대로 작동하지 않습니다. 관련 객체를 할당 할 때, 조건이 삽입에 사용하지 않는 것; 단지 연결을 읽을 때.
이러한 솔루션 중 어느 것도이 변경되었습니다 협회 조건 주위의 행동처럼 보인다, 어떤 이유로 레일 5. 제대로 작동하지 않습니다. 관련 객체를 할당 할 때, 조건이 삽입에 사용하지 않는 것; 단지 연결을 읽을 때.
내 솔루션 협회에 대한 setter 메소드를 오버라이드 (override)하는 것이었다 :
has_one :photo, -> { photo_type: 'primary_photo'}, as: 'attachable', dependent: :destroy def photo=(photo) photo.photo_type = 'primary_photo' super end
-
==============================
10.당신은 SecondaryPhoto 모델을 같이 추가 할 수 있습니다 :
당신은 SecondaryPhoto 모델을 같이 추가 할 수 있습니다 :
class SecondaryPhoto < Photo end
has_one에서 class_name을 : secondary_photo 다음을 건너 뛸?
from https://stackoverflow.com/questions/2494452/rails-polymorphic-association-with-multiple-associations-on-the-same-model by cc-by-sa and MIT license
'RUBY-ON-RAILS' 카테고리의 다른 글
[RUBY-ON-RAILS] 데이터베이스에 배열을 저장 : 직렬화 된 배열 대 JSON (0) | 2020.02.13 |
---|---|
[RUBY-ON-RAILS] has_many를 통해 대 has_and_belongs_to_many (0) | 2020.02.13 |
[RUBY-ON-RAILS] SCSS 파일의 레일 4 이미지 경로, 이미지 URL 및 자산 URL이 더 이상 작동하지 (0) | 2020.02.13 |
[RUBY-ON-RAILS] 한 번에 사용자 당 고안 제한 한 세션 (0) | 2020.02.13 |
[RUBY-ON-RAILS] 레일 3 'config.autoload_paths'에 lib 디렉토리를 추가하면 내 모듈을 자동로드하지 않습니다 (0) | 2020.02.13 |