restful_authentication AASM状態を拡張するより良い方法
-
07-07-2019 - |
質問
最近、アプリの1つで最新バージョンのrestful_authentication(github)のaasm状態を拡張する必要がありました。 " include Authorization :: AasmRoles"を削除し、プラグインから既存の状態とイベントをコピーし、追加の" published"をサポートするために必要な変更を加えました。アカウントモデルの状態。
これを処理するよりクリーンな方法はありますか?つまり状態イベントをオーバーライドするだけですか?プラグインを使用して新しいイベントをそのまま追加できましたが、restful_authに既にある状態イベントをオーバーライドすることはできなかったため、インクルードを削除し、開始点としてそれを使用して自分で書き出す必要がありました。
解決
AASMでの状態の追加は、新しいStateオブジェクトを作成することで構成されます。このオブジェクトは、次のようにAASM :: StateMachine [User] .states配列に追加されます。
def create_state(name, options)
@states << AASM::SupportingClasses::State.new(name, options) unless @states.include?(name)
end
ここで注意すべきことは、一度設定された状態をオーバーライドすることはできません。同じ名前の状態が再度設定された場合、create_stateメソッドはそれを無視します。この問題を解決するには、ユーザーモデルで次のようなものを使用できます。
# this will remove the state with name :name from the states array
states = AASM::StateMachine[self].states
states.delete(states.find{ |s| s == :name })
# ... so we can define the state here again
aasm_state :name ...
状態を再定義するだけであれば、今は大丈夫です。ただし、状態を完全に削除する場合は、aasm_stateメソッドの本体で定義されているメソッドの定義も解除する必要があります。次のようなものを呼び出すことで可能になるはずです:
undef_method :name
状況はイベントの場合と同じである必要があります(コードで「状態」の代わりに「イベント」を使用するだけです)。理想的には、AASMモジュールで定義されたメソッドをオーバーライドするユーザーモデルのクラスメソッドにします。状態の場合、次のようになります。
def aasm_state(name, options={})
states = AASM::StateMachine[self].states
states.delete(states.find{ |s| s == name.to_sym })
super(name, options)
end
警告:私は正しくないかもしれません。このコードはテストされていませんが、AASMのソースコードを調べて理解しました。