복붙노트

[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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    10.당신은 SecondaryPhoto 모델을 같이 추가 할 수 있습니다 :

    당신은 SecondaryPhoto 모델을 같이 추가 할 수 있습니다 :

    class SecondaryPhoto < Photo
    end
    

    has_one에서 class_name을 : secondary_photo 다음을 건너 뛸?

  11. from https://stackoverflow.com/questions/2494452/rails-polymorphic-association-with-multiple-associations-on-the-same-model by cc-by-sa and MIT license