1

これは長いので、私に負担を与えてくれることを願っています。Rails STI Mystery - タイプがClassからStringに変更されているのはなぜですか?

私は、MrUpdateとTriggeredUpdateという2つのサブクラスを持つUpdateというモデルを持っています。単一テーブルの継承を使用して、更新する文字列として型フィールドを追加しました。

私の見解では、表示するものを決定するのがどのタイプかをチェックしています。私は更新がMrUpdateたとき、すなわち、それはfalseに評価され、タイプが文字列であるため、私はこれが失敗した

<% if @update.type == 'MrUpdate' %> 

を行う必要がありますと仮定しました。私はこの時点で@ update.type.typeがクラスであることに気づいた。更新がMrUdpateだったとき、すなわち、比較がtrueに評価され、

<% if @update.type == MrUpdate %> 

、それが働いた:OK、何でも、私が思ったので、私はそれを変更しました。それから、私は再び見直しをしましたが、もう一度失敗しました(つまり、アップデートがMrUpdateだった場合にはfalseに評価されます)。

脆弱性は、<%= link_to ...%>私が使用してjQueryでボタンにする呼び出し。私は私の見解では、このコードを配置した場合:

<br> 
<%= @update.type.type %><br> 
<%= @update.type %><br> 

<%= link_to 'New Note', new_note_path(:update_id => @update.id), :class => "ui-button" %> 

<br> 
<%= @update.type.type %><br> 
<%= @update.type %><br> 

を私が見る何ですか:

Class 
MrUpdate 

(the New Note button) 

String 
MrUpdate 

それは文字列にクラスから変更しています!だから私は間違っているか、ここで行方不明ですか?なぜそれをする必要がlink_何ですか?まず最初に私は文字列ではないがなぜそれが変わるのか本当に混乱しているのかどうかはわかりません。助けや説明が役に立ちます。私はちょうど一番上の方法と一番下の別の方法をコーディングすることができますが、その方法は狂気です。なぜこれが起こっているのか理解する必要があります。

+1

あなたは 'type'は予約語の一種だとは思わないのですか? – fl00r

+0

はい、この目的のために予約されています。MrUpdateとTriggeredUpdateをUpdateから派生させ、Updateに型フィールドを追加することは、私が読んだものから単一のテーブル継承を行う方法です。 –

答えて

1

私はここで何が問題であるかを考え出しました。方法を指してfl00rに感謝します。

はい、typeはRuby 1.8.7で予約されています。これは、呼び出し元のオブジェクトのクラスを示します。しかし、それが、単一テーブルの内在を示すために、またサブクラスの各インスタンスのクラスの名前を格納するために、Railsで使用されるフィールドの名前であることも事実です。

したがって、@ update.typeを使用して、型フィールドの値にアクセスしようとしました。しかし、これはRubyのObjectクラスの型メソッドを呼び出すことでした。何らかの理由で、link_to呼び出しの後、更新テーブルのtypeフィールドの値にアクセスしました。

これを理解しようとしているうちに、私はRailsコンソールで@ update.typeを呼び出し、このメッセージを見ました: "警告:オブジェクト#タイプは廃止され、オブジェクト#クラスを使用する"。最後に、私がしていたことを記録しました。電話を変更したとき:

<% if @update.class == MrUpdate %> 

すべてが正常に機能します。私はSTIについてGoogleから見つけたページのタイプを判断するための電話を見たことはありませんでした。これは、コントローラが1つしか使用しないことを推奨しているにもかかわらず、場合によってはインスタンスのクラスを決定する必要がある場合もあります。

だから、ダムミスパイロットエラー。しかし、これは誰かがこれに乗っ取られるのを助けるでしょう。

関連する問題