QA@IT
«回答へ戻る

バリエーションの説明を詳細に。

5599
 というように保存することができます。
 取得の方はUserBase.allですべて抽出できますのでブログmodelとはUserBaseを関連づけておけばいいのではないでしょうか。
 
-なお、ほかのバリエーションとしては、UserBaseに必要な列をすべて用意しておけばUserモデルは email,passwordで、OmniUserはuid,providerで利用することもできます(使われてない列が空になるだけです)。
+STIを利用したほかのバリエーションとして、
+* UserBaseに必要な列をすべて用意しておく
+UserモデルとOmniUserモデルで項目名を分けたい場合はUserBaseにすべての列を用意しておき、
+Userモデルは email,passwordで、OmniUserはuid,providerで利用することもできます(使われてない列が空になるだけです)。
+ただ、今回のケースならUserモデルとOmniUserモデルにアクセサメソッドがあればいいだけのように思います。
+同様にどちらかにだけ必要な項目もこのように定義することができます。
 
-また、UserBaseを用意した3つではなく、Userとそれを継承したOmniUserの2つだけで実装するという手もあるでしょう。(この場合UserのTypeはnilになるようです。)
+* Userとそれを継承したOmniUserの2つだけで実装する
+テンプレ的に親と継承する子2つでサンプルを書きましたが、UserBaseを用意する必要がないなら 3つではなく、
+`User < ActiveRecords::Base`と`OmniUser < User`の2つだけで実装したほうがいいかもしれません(この場合UserのTypeはnilになるようです)。
+
 UserBase.allで取得しても各アイテムは`instance_of?`で判別可能です。
 (先にあげた保存の例の3件しか入っていない場合)
 
 > UserBase.all[2].instance_of? OmniUser
 => true
 ```
+
+なるべく判別しなくても使える(使う側は実体がどちらか意識する必要がない)ようになっていたほうが綺麗ですけどね。

railsの場合はモデルの単一テーブル継承または多態化を利用するのがいいのではないかと思います。

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Single+table+inheritance

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

今回はSTI(Single Table Inheritance)の方でいいように思いますね。

UserBase モデル
User モデル
OmniUser モデル
の3つで設計する場合を考えると、
必要な項目はすべてUserBaseモデルに格納します。
まずは基本形として元々 uidとemail, providerとpasswordに分かれていたものを同じ列にしてみて考えてみます。
ここでは uidとauth_valueとしました。
モデルは以下のようになります。

class UserBase < ActiveRecord::Base
  accessible_attr: uid, auth_value
end

class User < UserBase
end

class OmniUser < UserBase
end

ただしUserBasesテーブルにはtype列を追加する必要があります。
(今回動作確認にあたってはrails g model UserBase uid:string auth_value:string type:stringで作ってモデルのaccessible_attr:からtypeを削除しちゃいました。)

こうすると

> u = UserBase.new
> u.uid = "uid"
> u.save

> u = User.new
> u.uid = "uid"
> u.save

> u = OmniUser.new
> u.uid = "uid"
> u.save

というように保存することができます。
取得の方はUserBase.allですべて抽出できますのでブログmodelとはUserBaseを関連づけておけばいいのではないでしょうか。

STIを利用したほかのバリエーションとして、

  • UserBaseに必要な列をすべて用意しておく
    UserモデルとOmniUserモデルで項目名を分けたい場合はUserBaseにすべての列を用意しておき、
    Userモデルは email,passwordで、OmniUserはuid,providerで利用することもできます(使われてない列が空になるだけです)。
    ただ、今回のケースならUserモデルとOmniUserモデルにアクセサメソッドがあればいいだけのように思います。
    同様にどちらかにだけ必要な項目もこのように定義することができます。

  • Userとそれを継承したOmniUserの2つだけで実装する
    テンプレ的に親と継承する子2つでサンプルを書きましたが、UserBaseを用意する必要がないなら 3つではなく、
    User < ActiveRecords::BaseOmniUser < Userの2つだけで実装したほうがいいかもしれません(この場合UserのTypeはnilになるようです)。

UserBase.allで取得しても各アイテムはinstance_of?で判別可能です。
(先にあげた保存の例の3件しか入っていない場合)

> UserBase.all[2].instance_of? UserBase
=> false
> UserBase.all[2].instance_of? OmniUser
=> true

なるべく判別しなくても使える(使う側は実体がどちらか意識する必要がない)ようになっていたほうが綺麗ですけどね。

railsの場合はモデルの単一テーブル継承または多態化を利用するのがいいのではないかと思います。

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Single+table+inheritance

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations


今回はSTI(Single Table Inheritance)の方でいいように思いますね。

UserBase モデル
User モデル
OmniUser モデル
の3つで設計する場合を考えると、
必要な項目はすべてUserBaseモデルに格納します。
まずは基本形として元々 uidとemail, providerとpasswordに分かれていたものを同じ列にしてみて考えてみます。
ここでは uidとauth_valueとしました。
モデルは以下のようになります。

```ruby
class UserBase < ActiveRecord::Base
  accessible_attr: uid, auth_value
end

class User < UserBase
end

class OmniUser < UserBase
end
```

ただしUserBasesテーブルにはtype列を追加する必要があります。
(今回動作確認にあたっては`rails g model UserBase uid:string auth_value:string type:string`で作ってモデルのaccessible_attr:からtypeを削除しちゃいました。)

こうすると
```ruby
> u = UserBase.new
> u.uid = "uid"
> u.save

> u = User.new
> u.uid = "uid"
> u.save

> u = OmniUser.new
> u.uid = "uid"
> u.save
```
というように保存することができます。
取得の方はUserBase.allですべて抽出できますのでブログmodelとはUserBaseを関連づけておけばいいのではないでしょうか。

STIを利用したほかのバリエーションとして、
* UserBaseに必要な列をすべて用意しておく
UserモデルとOmniUserモデルで項目名を分けたい場合はUserBaseにすべての列を用意しておき、
Userモデルは email,passwordで、OmniUserはuid,providerで利用することもできます(使われてない列が空になるだけです)。
ただ、今回のケースならUserモデルとOmniUserモデルにアクセサメソッドがあればいいだけのように思います。
同様にどちらかにだけ必要な項目もこのように定義することができます。

* Userとそれを継承したOmniUserの2つだけで実装する
テンプレ的に親と継承する子2つでサンプルを書きましたが、UserBaseを用意する必要がないなら 3つではなく、
`User < ActiveRecords::Base`と`OmniUser < User`の2つだけで実装したほうがいいかもしれません(この場合UserのTypeはnilになるようです)。

UserBase.allで取得しても各アイテムは`instance_of?`で判別可能です。
(先にあげた保存の例の3件しか入っていない場合)

```ruby
> UserBase.all[2].instance_of? UserBase
=> false
> UserBase.all[2].instance_of? OmniUser
=> true
```

なるべく判別しなくても使える(使う側は実体がどちらか意識する必要がない)ようになっていたほうが綺麗ですけどね。

5599
 ```
 
 ただしUserBasesテーブルにはtype列を追加する必要があります。
-(`rails g model UserBase uid:string auth_value:string type:string`で作ってモデルのaccessible_attr:からtypeを削除するんでもいいんですかね?)
+(今回動作確認にあたっては`rails g model UserBase uid:string auth_value:string type:string`で作ってモデルのaccessible_attr:からtypeを削除しちゃいました。)
 
 こうすると
 ```ruby

railsの場合はモデルの単一テーブル継承または多態化を利用するのがいいのではないかと思います。

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Single+table+inheritance

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

今回はSTI(Single Table Inheritance)の方でいいように思いますね。

UserBase モデル
User モデル
OmniUser モデル
の3つで設計する場合を考えると、
必要な項目はすべてUserBaseモデルに格納します。
まずは基本形として元々 uidとemail, providerとpasswordに分かれていたものを同じ列にしてみて考えてみます。
ここでは uidとauth_valueとしました。
モデルは以下のようになります。

class UserBase < ActiveRecord::Base
  accessible_attr: uid, auth_value
end

class User < UserBase
end

class OmniUser < UserBase
end

ただしUserBasesテーブルにはtype列を追加する必要があります。
(今回動作確認にあたってはrails g model UserBase uid:string auth_value:string type:stringで作ってモデルのaccessible_attr:からtypeを削除しちゃいました。)

こうすると

> u = UserBase.new
> u.uid = "uid"
> u.save

> u = User.new
> u.uid = "uid"
> u.save

> u = OmniUser.new
> u.uid = "uid"
> u.save

というように保存することができます。
取得の方はUserBase.allですべて抽出できますのでブログmodelとはUserBaseを関連づけておけばいいのではないでしょうか。

なお、ほかのバリエーションとしては、UserBaseに必要な列をすべて用意しておけばUserモデルは email,passwordで、OmniUserはuid,providerで利用することもできます(使われてない列が空になるだけです)。

また、UserBaseを用意した3つではなく、Userとそれを継承したOmniUserの2つだけで実装するという手もあるでしょう。(この場合UserのTypeはnilになるようです。)
UserBase.allで取得しても各アイテムはinstance_of?で判別可能です。
(先にあげた保存の例の3件しか入っていない場合)

> UserBase.all[2].instance_of? UserBase
=> false
> UserBase.all[2].instance_of? OmniUser
=> true
railsの場合はモデルの単一テーブル継承または多態化を利用するのがいいのではないかと思います。

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Single+table+inheritance

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations


今回はSTI(Single Table Inheritance)の方でいいように思いますね。

UserBase モデル
User モデル
OmniUser モデル
の3つで設計する場合を考えると、
必要な項目はすべてUserBaseモデルに格納します。
まずは基本形として元々 uidとemail, providerとpasswordに分かれていたものを同じ列にしてみて考えてみます。
ここでは uidとauth_valueとしました。
モデルは以下のようになります。

```ruby
class UserBase < ActiveRecord::Base
  accessible_attr: uid, auth_value
end

class User < UserBase
end

class OmniUser < UserBase
end
```

ただしUserBasesテーブルにはtype列を追加する必要があります。
(今回動作確認にあたっては`rails g model UserBase uid:string auth_value:string type:string`で作ってモデルのaccessible_attr:からtypeを削除しちゃいました。)

こうすると
```ruby
> u = UserBase.new
> u.uid = "uid"
> u.save

> u = User.new
> u.uid = "uid"
> u.save

> u = OmniUser.new
> u.uid = "uid"
> u.save
```
というように保存することができます。
取得の方はUserBase.allですべて抽出できますのでブログmodelとはUserBaseを関連づけておけばいいのではないでしょうか。

なお、ほかのバリエーションとしては、UserBaseに必要な列をすべて用意しておけばUserモデルは email,passwordで、OmniUserはuid,providerで利用することもできます(使われてない列が空になるだけです)。

また、UserBaseを用意した3つではなく、Userとそれを継承したOmniUserの2つだけで実装するという手もあるでしょう。(この場合UserのTypeはnilになるようです。)
UserBase.allで取得しても各アイテムは`instance_of?`で判別可能です。
(先にあげた保存の例の3件しか入っていない場合)

```ruby
> UserBase.all[2].instance_of? UserBase
=> false
> UserBase.all[2].instance_of? OmniUser
=> true
```

回答を投稿

railsの場合はモデルの単一テーブル継承または多態化を利用するのがいいのではないかと思います。

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Single+table+inheritance

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

今回はSTI(Single Table Inheritance)の方でいいように思いますね。

UserBase モデル
User モデル
OmniUser モデル
の3つで設計する場合を考えると、
必要な項目はすべてUserBaseモデルに格納します。
まずは基本形として元々 uidとemail, providerとpasswordに分かれていたものを同じ列にしてみて考えてみます。
ここでは uidとauth_valueとしました。
モデルは以下のようになります。

class UserBase < ActiveRecord::Base
  accessible_attr: uid, auth_value
end

class User < UserBase
end

class OmniUser < UserBase
end

ただしUserBasesテーブルにはtype列を追加する必要があります。
rails g model UserBase uid:string auth_value:string type:stringで作ってモデルのaccessible_attr:からtypeを削除するんでもいいんですかね?)

こうすると

> u = UserBase.new
> u.uid = "uid"
> u.save

> u = User.new
> u.uid = "uid"
> u.save

> u = OmniUser.new
> u.uid = "uid"
> u.save

というように保存することができます。
取得の方はUserBase.allですべて抽出できますのでブログmodelとはUserBaseを関連づけておけばいいのではないでしょうか。

なお、ほかのバリエーションとしては、UserBaseに必要な列をすべて用意しておけばUserモデルは email,passwordで、OmniUserはuid,providerで利用することもできます(使われてない列が空になるだけです)。

また、UserBaseを用意した3つではなく、Userとそれを継承したOmniUserの2つだけで実装するという手もあるでしょう。(この場合UserのTypeはnilになるようです。)
UserBase.allで取得しても各アイテムはinstance_of?で判別可能です。
(先にあげた保存の例の3件しか入っていない場合)

> UserBase.all[2].instance_of? UserBase
=> false
> UserBase.all[2].instance_of? OmniUser
=> true
railsの場合はモデルの単一テーブル継承または多態化を利用するのがいいのではないかと思います。

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Single+table+inheritance

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations


今回はSTI(Single Table Inheritance)の方でいいように思いますね。

UserBase モデル
User モデル
OmniUser モデル
の3つで設計する場合を考えると、
必要な項目はすべてUserBaseモデルに格納します。
まずは基本形として元々 uidとemail, providerとpasswordに分かれていたものを同じ列にしてみて考えてみます。
ここでは uidとauth_valueとしました。
モデルは以下のようになります。

```ruby
class UserBase < ActiveRecord::Base
  accessible_attr: uid, auth_value
end

class User < UserBase
end

class OmniUser < UserBase
end
```

ただしUserBasesテーブルにはtype列を追加する必要があります。
(`rails g model UserBase uid:string auth_value:string type:string`で作ってモデルのaccessible_attr:からtypeを削除するんでもいいんですかね?)

こうすると
```ruby
> u = UserBase.new
> u.uid = "uid"
> u.save

> u = User.new
> u.uid = "uid"
> u.save

> u = OmniUser.new
> u.uid = "uid"
> u.save
```
というように保存することができます。
取得の方はUserBase.allですべて抽出できますのでブログmodelとはUserBaseを関連づけておけばいいのではないでしょうか。

なお、ほかのバリエーションとしては、UserBaseに必要な列をすべて用意しておけばUserモデルは email,passwordで、OmniUserはuid,providerで利用することもできます(使われてない列が空になるだけです)。

また、UserBaseを用意した3つではなく、Userとそれを継承したOmniUserの2つだけで実装するという手もあるでしょう。(この場合UserのTypeはnilになるようです。)
UserBase.allで取得しても各アイテムは`instance_of?`で判別可能です。
(先にあげた保存の例の3件しか入っていない場合)

```ruby
> UserBase.all[2].instance_of? UserBase
=> false
> UserBase.all[2].instance_of? OmniUser
=> true
```