Rails — STIなしのタイプ列を使用しますか?


82

type単一テーブル継承(STI)を呼び出さずに呼び出された列を使用したい-をtype保持する通常の列になりたいだけですString

Railsが単一テーブル継承を期待せず、例外をスローせずにこれを行うにはどうすればよいThe single-table inheritance mechanism failed to locate the subclass...This error is raised because the column 'type' is reserved for storing the class in case of inheritance.ですか?

これを行う方法についてのアイデアはありますか?

回答:


135

Rails 3.1set_inheritance_columnは非推奨でありnil、次のように名前として使用することもできます。

class Pancakes < ActiveRecord::Base
    self.inheritance_column = nil
    #...
end

実際には、で変更されたように見えますrails 3.2apidockによると: 'このメソッドは非推奨であるか、最新の安定バージョンに移動されています。最後の既存のバージョン(v3.1.0)がここに表示されます。ヒントをありがとう!
バトキンス2012年

3.1で非推奨になり、3.2で削除されたと思います
Valentin Nemcev 2012年

2
@Batkinsinheritance_columnリーダーが移動しました(したがって、「非推奨または移動」の通知)。inheritance_columnインスタンス変数を直接設定することは意図されたものであり、非推奨ではありません。
lulalala 2013

Rails 5.1で
作業

22

以下を使用して、STI列名をオーバーライドできますset_inheritance_column

class Pancakes < ActiveRecord::Base
    set_inheritance_column 'something_you_will_not_use'
    #...
end

したがって、何にも使用しない列名を選択して、それをにフィードしset_inheritance_columnます。


2
データベースにその列を実際に作成する必要がありますか?
kvass 2011

ありがとう、これはうまくいきました。フレームワークは絶対にすべきではありません!!!!! EVER !!!! テーブルフィールドに名前を付けることができないものを指示します。これは、レガシーデータセットにとっては非常に悪いことです。
ジョン

5
@Jon:Railsはレガシーデータや他の人とうまく遊ぶことを本当に気にしません、Railsはそれに対してあまりにも多くの態度を持っています。ある程度の努力でそれ自体を動作させることはできますが、Railsが計画していないことを行う必要がある場合は、常に少し戦うことになります(残念ながら、多くの基本的なデータベースの概念が含まれています)。他のRailsの人は確かにイデオロギーの問題を指摘するために私と一緒に動揺されるように:) OTOH、私はプロの異端者だ
muは短すぎる

10
Rails / Rubyは設定より規約を好むので、正しいと思うユースケースに合わせて最適化しようとしているという考えだと思います。
イブラヒム

21

この質問はかなり古く、あなたが尋ねている質問とは少し異なりますが、列タイプまたはsomething_typeに名前を付けたいと思うときはいつでも、typeの同義語を検索して、代わりにそれを使用します。

いくつかの選択肢があります:種類、並べ替え、種類、カテゴリ、セット、ジャンル、種、順序など。


10

Rails 4.x

Rails 4アプリで問題が発生しましたが、Rails 4ではset_inheritance_columnメソッドがまったく存在しないため、使用できません。

私のために働いた解決策は、次のように、ActiveRecordinheritance_columnメソッドをオーバーライドすることによって単一テーブル継承を無効にすることでした。

class MyModel < ActiveRecord::Base

  private

  def self.inheritance_column
    nil
  end

end

それが役に立てば幸い!


8
より単純なバージョン:class MyModel < ActiveRecord::Base self.inheritance_column = nil end。参考:apidock.com/rails/ActiveRecord/ModelSchema/ClassMethods/...
Benj

1
Rails4.2.2で動作します。おそらく、変更を行った後、サーバーまたはスプリングを再起動しませんでしたか?
ベンジ2015年

1
そして、他のユーザーは私がコメントしたより単純なバージョンが役に立つと思うかもしれません。リロードの問題に関しては、私は専門家ではありませんが、クラス定義をアンロードしてリロードせずにクラスプロパティを自動的にリロードしないようにすることは理にかなっています。
ベンジ2015年

2
私はあなたの反応を理解していません、私はあなたの答えに有用な追加を与えようとしているだけです。なぜ気分が悪くなるのですか?私は平和に来る
ベンジ2015年

2
@Benjあなたが参照しているコメントはすべて削除されたようですので、今はあなたが自分自身と議論しているように見えます。;)
Joshua Pinter

0

すべてのモデルに対してこれを実行する場合は、これを初期化子に固定できます。

ActiveSupport.on_load(:active_record) do
  class ::ActiveRecord::Base
    # disable STI to allow columns named "type"
    self.inheritance_column = :_type_disabled
  end
end

またはさらに良いことに-ApplicationRecordで
アレクサンダー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.