2016-09-02 2 views
0

레일에서 다형성 연관을 이해하는 데 어려움이 있습니다. 방법을 지원하는 데 필요한 스키마와 구문 이외의 많은 차이가 아니다다형성 연관 - 레일

class Picture < ApplicationRecord 
    belongs_to :employee 
    belongs_to :product 
end 

class Employee < ApplicationRecord 
    has_many :pictures 
end 

class Product < ApplicationRecord 
    has_many :pictures 
end 

답변

3

두 번째 경우 그림 테이블에 employee_id 및 product_id라는 두 개의 외래 키를 추가해야합니다.

곳으로 마이그레이션와 클래스의 이름이됩니다

t.integer :imageable_id 
t.string :imageable_type 

imagable_type 필드, 즉 사진 테이블에 두 필드를 추가합니다 사진에 첫 번째 경우 t.references :imageable, polymorphic: true에 당신은이 모델을 연결하고 imagable_id의를 개최한다 누구 그 기록의 이드.

예를 들어,

이 사진 테이블의

일반적인 행이 그래서 여기

id | name | imagable_id | imagable_type | 

1 | pic1 | 1   | Employee  | 
2 | pic2 | 3   | Product  | 

모양을, 첫 번째 행의 그림 속할 ID 1. 두 번째 행과 직원의 사진을 들고 직원 모델에 속하는 것 to id를 가진 제품의 그림을 보유한 제품 모델

첫 번째 접근법의 장점 미래에 외래 키를 추가 할 필요없이 다른 모델을 다른 모델과 연결할 수 있습니다.

그냥 라인

has_many :pictures, as: :imageable 

를 추가하고 연결이 설정됩니다.

3

에서

class Picture < ApplicationRecord 
    belongs_to :imageable, polymorphic: true 
end 

class Employee < ApplicationRecord 
    has_many :pictures, as: :imageable 
end 

class Product < ApplicationRecord 
    has_many :pictures, as: :imageable 
end 

다르다. belongs_to : imageable 관계가 상대적으로 많은 경우 유스 케이스로 이해하기 시작합니다. 표준 명명 방법을 사용하면 여러 개의 belongs_to 연관을 두 개, "MODEL_able"및 대상 모델의 ID를 참조하는 ID로 표시하는 데 필요한 n 개의 필드를 줄일 수 있습니다. 이것은 각각의 belongs_to 모델에 대해 MODEL_id를 갖는 것이 유리합니다. 거대한 승리이기는하지만 매우 익숙한 좋은 일입니다.

0

Imagin 당신은이 모델이 있습니다 포스트, 아이디어, 제 및 모든 세 가지에 대한 코멘트 모델을 갖고 싶어! 당신과 같은 의견을 세 개의 테이블을 가질 수 있습니다 : 당신이 모델을 관련이에 따라 각 코멘트를 한 일반 코멘트 모델을 가지고 저장할 수 또는 PostComment, IdeaCommnet, ArticleComment. @Karan 인 Purohit으로 언급 :)

1
Without Polymorphic 
20160902065429_create_employee_images 
class CreateEmployeeImages < ActiveRecord::Migration[5.0] 
    def change 
     create_table :employee_images do |t| 
      t.integer :employee_id 
      t.string :image 

      t.timestamps 
     end 
    end 
end 
20160902065445_create_product_images 
class CreateProductImages < ActiveRecord::Migration[5.0] 
    def change 
     create_table :product_images do |t| 
      t.integer :product_id 
      t.string :image 
      t.timestamps 
     end 
    end 
end 

app/model/employee.rb 
class Employee < ApplicationRecord 
    has_many :employee_images 
end 

app/model/product.rb 
class Product < ApplicationRecord 
    has_many :pictures, as: :imageable 
end 

app/model/employee_image.rb 
class EmployeeImage < ApplicationRecord 
    belongs_to :employee 
end 

app/model/product_image.rb 
class ProductImage < ApplicationRecord 
    belogs_to :product 
end 

With Polymorphic 

db/migrate/20160902063459_create_products.rb 
class CreateProducts < ActiveRecord::Migration[5.0] 
    def change 
     create_table :products do |t| 
      t.string :name 
      t.timestamps 
     end 
    end 
end 

db/migrate/20160902063513_create_employees.rb 
class CreateEmployees < ActiveRecord::Migration[5.0] 
    def change 
     create_table :employees do |t| 
      t.string :name 
      t.timestamps 
     end 
    end 
end 

db/migrate/20160902063602_create_pictures.rb 
class CreatePictures < ActiveRecord::Migration[5.0] 
    def change 
     create_table :pictures do |t| 
      t.string :picture 
      t.integer :imageable_id 
      t.string :imageable_type 
      t.string :image 

      t.timestamps 
     end 
    end 
end 

app/model/employee.rb 
class Employee < ApplicationRecord 
    has_many :pictures, as: :imageable 
end 

app/model/picture.rb 
class Picture < ApplicationRecord 
    belongs_to :imageable, polymorphic: true 
end 

app/model/product.rb 
class Product < ApplicationRecord 
    has_many :pictures, as: :imageable 
end 

1- 다형성없이. 우리는 같은 것을하기 위해 두 개의 다른 테이블을 사용했습니다. 2- 다형성을 사용하여 세 번째 다형성 모델에 두 개 이상의 모델의 이미지를 저장하는 단일 모델 만 생성했습니다.
세 번째 테이블에 두 개의 coulms가 필요합니다. 하나는 stroe 모델 클래스 이름이고 두 번째는 레코드 ID입니다. 우리는 두 컬럼을 취할 수 있지만 컬럼 이름은 imageable + id imageable + type 과 같아야합니다. 여기서는 poly_id poly_type을 사용할 수있는 것처럼 이미지 가능의 모든 이름을 사용할 수 있습니다.하지만 우리는 모델에서 무엇을 사용하는지 확인해야합니다.

poly_id 및 poly_type을 사용하는 경우 belogs_to : poly, polymorphic : picture.rb 및 has_many : pictures에서 true를 사용해야합니다. : poly : employee.rb 및 product.rb에서 모두 둘 다.

+0

위대한 설명, 감사합니다 :-) –