2

は、モデルのユーザーを考えてみましょう:Railsモデルでフィールドを「オーバーロードする」最適な方法は何ですか?

私はアプリケーションを構築し
User(id: integer, name: string, email: string, status: string) 

、状態はデータベース内のフィールドでした。しかし、新しい要件とは、状態が動的に計算されるような変更を意味します。たとえば、日曜日に姓がAで始まる場合、ステータスは「not ok」です。

私は、次のよう 何かをUserモデルでこの機能をカプセル化したい

Class User < ActiveRecord::Base 

    def status 
    if is_sunday && last_name.starts_with('A') 
     return 'not ok' 
    else 
     return status 
    end 
    end 

end 

これを行うための最善の方法は何ですか?上記のコードがうまくいけば、データベースのフィールドをメソッドでオーバーライドするのは悪い習慣です。

また、上記のコードを使用する方法get_statusを作成することもできます。しかし、この場合、アプリケーション全体を通してすべての参照をstatusに変更する必要があります。それは良いとは思わない。

+2

fwiw、私は解決策としてその方法で完全に問題ありません。私は 'get_status'を追加すると、ユーザーのステータスを取得する第2の方法を作成しているので、もっと混乱していると思います。 – thewillcole

答えて

4

私はActiveRecord::Base documentationで、ActiveRecordが提供するデフォルトのアクセサーを上書きできることを確認しました。もちろん、statusを使用することはできません。なぜなら、このメソッドをやや再帰的にするからです。

希望する場合は、read_attribute(:attribute_name)またはself[:attribute_name]を使用して、DBの列値にアクセスできます。だから、長い話は、あなたのアクセサが短くなってしまう:

Class User < ActiveRecord::Base 
    def status 
    if is_sunday && last_name.starts_with('A') 
     'not ok' 
    else 
     read_attribute(:status) 
    end 
    end 
end 

UPDATE:私はそれを試してみたし、それはあなたが明示的にこのメソッドを呼び出していない場合は、DBの内容を取得するので、しかし、注意を払って作品を...のためにたとえば、テーブルを照会して、status = "not ok"のユーザーを見つけようとすると、驚きを受けることができます。

+1

Rails 3.2では、 'read read_attribute(:status)'を 'super'で置き換えますか? – Zabba

+0

'super'はRubyのキーワークなので、以前のRailsバージョンでもうまくいくはずですが、この文脈で私には少しあいまいです。私はこれを明示的にすることを好むでしょう。 –

+1

+1、返信文は必要ですか? – stephenmurdoch

関連する問題