1

を公開私の目標:は継承されたモデルの上に追加のフィールドを追加し、すべてのスーパーと子クラスのフィールドに

私は異なるプロファイルで、ユーザーの二つの異なるタイプを作成しようとしています。

BarberClientBarberProfile、およびClientProfile

は、私は私のベースUseremailpasswordなどの情報を含むオブジェクト、そして工夫はを追跡し、他のすべてのフィールドを持っています。

ベースUserモデルには、すべてのユーザーに必要な基本情報をすべて記録するProfileがあります。 ClientBarber:たとえば、first_namelast_nameavatarなど

は、私は、ユーザーの二つの異なるタイプを作成するために、単一テーブル継承を使用しています。

これらのタイプのユーザーのそれぞれには、ベースがProfileに関連付けられていて、それぞれBarberProfileClientProfileに属する追加のフィールドがあります。

Barberには、Clientには必要なものがあります。例えば、bioClientProfileにはClientが必要ですが、Barberは必要ありません。たとえば、hair_typeです。

私が現在持っている、と私の問題:

上述したように、私はUserProfile用のテーブルを作成しました。だから私はuser.profile.first_nameに電話することができます。追加のフィールドを追加するには、BarberProfileテーブルとClientProfileテーブルを作成しました。

ユーザータイプがBarberの場合は、user.profile.bioを参照できるようにしたいと考えています。しかしbioはベースプロファイルの一部ではありません。この場合、私は必要なものすべてを得るためにProfileを関連付けて関連付け、BarberProfileを関連付けなければなりません。私はちょうどuser.profile.first_nameuser.barber_profile.bioをやることができますが、それは面倒です、私は基本的に同じタイプのモデルから2つの異なる関連付けをしています。 にすべてのフィールドを継承させてProfileから受け取り、固有のBarberフィールドを上に追加するのは簡単なことです。

Railsでこれを行うにはどうすればよいですか?

編集:私はこれをしたい主な理由の一つはので、私はBarberで同じフォーム内first_namebioのようなものを更新することができます。同じように、Clientの場合、同じフォーム内のfirst_namehair_typeが同じフォーム内にあります。

答えて

1

プロファイルとクライアント/ BarberProfileのユーザーに2つの関連付けを使用しないようにするには、ClientProfileとBarberProfileをProfile(単一テーブルの継承)に拡張し、それぞれに "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は別のテーブルとして存在しますか?この設定で1つのフォームからbioを更新することは可能ですか? – Doug

+0

はい、BarberProfileDataには独自のテーブルが必要です。更新については、可能でなければなりません。とにかく、いつでも更新アクションをカスタマイズして、正しいfields_forを設定するのに必要なものを実行することができます。 – arieljuod

0

これは、Multiple Table Inheritanceの良い使用例のようです。 MTIでは、追加のテーブルを使用してベースモデルを飾ります。

MTIへの主な利点は、clientsbarbersテーブルは(彼らは、単一のテーブルにそれを呼ぶ理由厥)設計によりusersにすべてを詰め込むする必要STI VSそのタイプのための特定の列を含めることができるということです。

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 gemの例です。 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)を使用してすべてのタイプの装飾ユーザーを取得できます。

関連する問題