2017-05-07 19 views
1

私はenum属性verification_statusといくつかのクラスが使用するモジュールがあります。Railsの5:読み取り専用のenum属性

included(self) do 
    enum verification_status: { dont_verify: 0, pending: 1, in_review: 2, rejected: 3, approved: 4 } 
end 

が、私はこの属性は読み取り専用にする必要があるだろうという方法で、必要に1つの専用の方法以外では、例外を伴って失敗するか、何らかのエラーを返す必要があります。その理由は、の別の属性変更の結果として変更する必要があるため、検証可能なオブジェクトのadd_verification(これは専用メソッド)を呼び出すと、いくつかのプロパティを持つVerificationが前のリストに追加されますそのオブジェクトの検証が行われ、そのオブジェクトのステータスがverification_statusに設定されています。

私はattr_readonlyを認識していますが、それは本当に私が心配しているすべてのケースをカバーしていません。前もって感謝します!

答えて

1

標準レールコードは読み取り専用列挙型をサポートしていませんしたがって、ハックの一種として以下を考慮してください。一般的に列挙型の値は、2つの方法で設定することができます直接列挙型のカラム名に値を設定することにより、

  • - あなたが述べたように、この動作は、attr_readonlyを用いて抑制することができますが、私は方法はないだろうと思うに残さ実際にはに設定されています。つまり、私たちはセッターメソッドを自分たちで再定義し、
  • を呼び出してrecord.enum_value!と呼びます.bangメソッドは動的に定義され、値を設定する代わりにエラーをスローするように再定義する必要があります。だから、

enumを宣言した後、次のラインに沿って、setterメソッドを再定義する必要があります:実際に列挙値を設定し、その後

enum verification_status: { dont_verify: 0, pending: 1, in_review: 2, rejected: 3, approved: 4 } 

# redefine the enum setter 
define_method("verification_status=") do |args = nil| 
    raise "use `add_verification` instead to modify this" 
end 

# redefine the bang enum setters 
verification_statuses.each do |status, value| 
    define_method("#{status}!") do 
    raise "use `add_verification` instead to modify this" 
    end 
end 

、あなたはプライベートwrite_attributeメソッドを使用する必要があります数値の列挙型の値を使用して直接属性を設定する例:

write_attribute(:verification_status, self.class.verification_statuses[:pending]) 
#=> 1 

# verify that the value has been indeed set 
verification_status 
#=> "pending" 
+0

私は 'add_verification'メソッドの正確さについて1つの質問があります。最後に 'save'を呼び出すことは私にとっては奇妙に見えます):def add_verification(verification)' 'write_attribute(:verification_status、Verification.statuses [verification.status]) ' '検証 'verification' ' save' 'end' 私が正しく理解していれば、' write_attribute'はメモリに属性を変更するだけで、DBに保存することはありません。だから、私は 'save'と呼んでいます(フォーマットが貧弱な人は申し訳ありませんが、私ができることは最高です)。 –

+1

'write_attribute'はメモリ内の属性のみを設定し、' save'を呼び出さなければなりません。なぜそれはあなたに奇妙に見えるのですか? 'save'は、検証ステータスだけでなく、変更されたすべての属性(もしあれば)を保存するという事実にはおそらく問題があります。必要に応じて 'update_column'メソッドを使用して、dbで直接属性を設定することもできます。[docs](http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-update_column)メソッドを参照してください。多くのための。 – BoraMa

+0

私はそれを今チェックすることはできませんが、 '<<'は '検証 '配列に加えられた変更を保存すると思います。だから私は 'save'を使うとDBの更新が重複しているのですが、そうですか?私がいれば、この場合は 'update_column'が良いアプローチです。 Díky! –

関連する問題