1

내 목표를 노출 : 나는 사용자의 두 가지 유형을 만들려고 해요상속 된 모델의 상단에 추가 필드를 추가하고 모든 슈퍼와 자식 클래스 필드를

다른 프로파일.

Barber, Client, BarberProfileClientProfile

나는 나의 기본 Useremail, password 같은 정보를 포함 객체 및 고안은 추적을 유지 다른 모든 필드를 가지고있다.

User 모델에 Profile이라는 하나의 기본 정보를 제공하여 모든 사용자가 갖기를 바라는 모든 기본 정보를 추적하고 싶습니다. ClientBarber : 등 예, first_name, last_name, avatar,

을 위해 나는 사용자의 두 가지 유형을 생성하는 단일 테이블 상속을 사용하고 있습니다.

각 유형의 사용자가 각각 Profile이라는 기본 단위를 갖고 있으며 각각 BarberProfileClientProfile에 속하는 추가 입력란을 갖고 싶습니다.

Barber에는 필요하지만, Client에는 필요하지 않은 것이 있습니다. 예를 들어 bio입니다. ClientProfile에는 Client이 필요하지만, Barber은 필요하지 않습니다. 예 : hair_type.

는 내가 현재 가지고 있고, 내 문제가 무엇 :

위에서 언급 한 바와 같이, 나는 UserProfile에 대한 테이블을 만들었습니다. 그래서 user.profile.first_name으로 전화 할 수 있습니다. 여분의 필드를 추가하기 위해 BarberProfileClientProfile 테이블을 만들었습니다.

사용자 유형이 Barber 인 경우 user.profile.bio을 참조 할 수 있습니다. 그러나 bio은 기본 프로필의 일부가 아닙니다. 그래서이 경우에는 관련된 모든 항목을 얻기 위해 Profile을 연결하고 BarberProfile을 연결해야합니다. 나는 단지 user.profile.first_nameuser.barber_profile.bio을 할 수 있지만 지저분한 느낌이 들며 본질적으로 같은 유형의 모델과는 두 개의 서로 다른 연관을 만들고 있습니다. 은 모든 필드를 상속 받아 Profile에서 상속 받고 그 위에 고유 한 Barber 필드를 추가하는 것이 간단한 일입니다.

레일스에서이 작업을 수행하는 방법은 무엇입니까?

편집 : 나는 Barber에 대해 동일한 형태 내에서 first_namebio 등을 갱신 할 수 있도록이가하고 싶은 주된 이유 중 하나. 마찬가지로 Client의 경우 동일한 양식 내의 first_namehair_type이 있습니다.

답변

1

Profile 및 Client/BarberProfile에 대해 두 개의 연관을 사용하지 않으려면 ClientProfile 및 BarberProfile이 프로필 (단일 테이블 상속)을 확장하고 각 프로필에 "barber_profile_data" 나는 그것을 어떻게 부를 지 모르겠다.) 긴 메서드 호출을 수정하려면 위임 된 메서드를 사용할 수 있습니다. 당신이 "@의 barber.bio"를 수행 할 때

class Barber > User 
    has_one :barber_profile 
    delegate :bio, to: :barber_profile 

class Client < User 
    has_one :client_profile 
    delegate :first_name, to: :client_profile 

class BarberProfile < Profile 
    has_one :barber_profile_data 
    delegate :bio, to: :barber_profile_data 

class ClientProfile < Profile 
    has_one :client_profile_data 
    delegate :first_name, to: :client_profile_data 

그런 다음, 그것은 "barber.barber_profile.barber_profile_data.bio @"내부적으로 호출해야합니다.

+0

입력 해 주셔서 감사합니다. 프로파일을 확장하는 것이 내 첫 번째 본능이었고 꽤 직관적 인 것처럼 생각하기를 좋아합니다. 따라서 barber_profile_data는 별도의 테이블로 존재합니까? 이 설정으로 한 양식에서 바이오를 업데이트 할 수 있습니까? – Doug

+0

예, BarberProfileData에는 자체 테이블이 있어야합니다. 업데이트에 대해서는 레일스 form_for 메소드 fields_for를 확인하고 그걸로 재생할 수 있어야합니다. 어쨌든 항상 업데이트 작업을 사용자 정의하고 올바른 fields_for를 설정하는 데 필요한 작업을 수행 할 수 있습니다. – arieljuod

0

이것은 Multiple Table Inheritance의 좋은 사용법처럼 들립니다. MTI에서는 추가 테이블을 사용하여 기본 모델을 장식합니다.

MTI의 주요 장점은 clientsbarbers 표는 당신이 설계 users에 모든 것을 벼락 공부하는 데 필요한 STI 대 유형의 특정 열을 포함 할 수 있다는 것입니다 (그들은 하나의 테이블라고 부르는 이유 먹으 렴).

create_table "barbers", force: :cascade do |t| 
    # only the specific attributes 
    t.text  "bio" 
end 

create_table "clients", force: :cascade do |t| 
    # only the specific attributes 
    t.string "hair_type" 
end 

create_table "users", force: :cascade do |t| 
    t.string "email" 
    t.string "first_name" 
    t.string "last_name" 
    # ... all the other common attributes 
    t.integer "actable_id" 
    t.string "actable_type" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
end 

이것은 ActiveRecord::ActsAs 보석의 예입니다. BarberClient 사실 서브 클래스되어서는 안된다는

class User < ApplicationRecord 
    actable 
end 

class Barber < ApplicationRecord 
    acts_as :product 
end 

class Barber < ApplicationRecord 
    acts_as :product 
end 

참고. ActiveRecord::ActsAs 대신 "작동 가능한"클래스에 위임합니다.

Barber.all 또는 Client.all을 입력하여 특정 유형을 가져 오거나 User.all.map(:specific)을 사용하여 모든 유형의 장식 사용자를 얻을 수 있습니다.