당신이 찾고있는 것은 역 다형성 연관입니다. 다형성 연관을 사용하면 한 모델을 여러 모델에 연결할 수 있습니다. 역 다형성 연관을 사용하면 여러 모델을 하나의 단일 모델로 연결할 수 있습니다. 설정하기가 다소 까다 롭지 만 일단 문제가 발생하면 아무런 문제가 없습니다.
이 작업을 수행하려면 Person
모델과 각기 다른 역할에 대한 중간 역할을하는 다른 모델이 필요합니다. 이 중재 모델은 실제로 다형성 연관이있는 모델입니다. 귀하의 Person 모델은 has_many
모델이며 다양한 롤 모델은 has_one
입니다. 그런 다음 :through
을 사용하여 코드가 다른 것을 알지 못하게 나머지 연결을 만듭니다. Shazam!
다음은 Person
및 CardHolder
모델로 수행하는 방법의 예입니다. 나는 여분의 모델을 호출하고있어 Role
그 당연한 선택처럼 보인다 때문에 :
class Person < ApplicationRecord
has_many :roles
# Reach through the Roles association to get the CardHolders, via polymorphic :rollable.
# Unfortunately, you can't has_one, so you'll have to enforce uniqueness in Role
# with a validation.
has_many :card_holders, through: :roles, source: :rollable, source_type: 'CardHolder'
end
class Role < ApplicationRecord
belongs_to :person
# Here is where our actual polymorphic connection is:
belongs_to :rollable, polymorphic: true
end
class CardHolder < ApplicationRecord
# The other side of the polymorphic connection, with has_one:
has_one :role, as: :rollable
# Get the person via the role, just like the inverse:
has_one :person, through: :role
end
데이터베이스 설정은 다음과 같이이다 : 그것은 매우 간단합니다 사용
class CreatePeople < ActiveRecord::Migration[5.1]
def change
create_table :people do |t|
t.string :name
# put in whatever other Person columns you need
t.timestamps
end
end
end
class CreateRoles < ActiveRecord::Migration[5.1]
def change
create_table :roles do |t|
t.references :person, index: true
t.references :rollable, polymorphic: true, index: true
t.timestamps
end
end
end
class CreateCardHolders < ActiveRecord::Migration[5.1]
def change
create_table :card_holders do |t|
t.integer :card_id
t.datetime :last_entrance
# put in whatever other columns you need
t.timestamps
end
end
end
:
> p = Person.create(name: "Sven Reuter")
# directly add a card holder
> p.card_holders << CardHolder.create(card_id: 1, last_entrance: Time.current)
# build a role instead
> p.roles.build(rollable: CardHolder.new(card_id: 2, last_entrance: Time.current)
# get all of the roles
> p.roles
그 매우 똑바로 & 깨끗하게 보입니다, 나는 그것을 시도해 볼 것입니다. 고맙습니다. –