ファウルを超えた検証

通常、レールでの検証については良いことだけが言われます。 今日は、システムがクラッシュする状況について説明します。



状況の時間



ユーザーを登録するとき、通常、パスワードの確認を行います。 問題ありません、追加:確認=> true。 しばらくすると、モバイルアプリケーションがサイトに表示され、登録も実装されますが、パスワードの確認はありません。 この場合の対処方法



猫の下のソリューション





最も一般的な答えは、コントローラーでpassword_confirmationを手に入れることです。 ちょっと待って パスワード確認はユーザーモデルと何の関係がありますか? 一般的なパスワード確認とは何ですか? そして、メールの確認(はい、そうする人もいます)?



状況2



同じ登録。 通常、メールが必要です。 プロダクトオーナーは、ソーシャルとの統合タスクを追加します。 ネットワーク。 twitterで認証ドキュメントを確認したところ、メールが表示されないことがわかりました。 もちろん、承認後、誰かが電子メールの入力を求めてきますが、私たちの場合、このマニュアルは反対です。 また、メールなしでポイントを認証する必要がありますが、とにかく登録フォームにはメールが必要です。 そして、この場合に何をすべきか?



聞いた答え:

  1. 登録時に検証をスキップします。
  2. 偽のメールを送る-qwerty@twitter.fake.com
  3. ハッキングによってエラーからエラーメッセージを切り取り、すべてが正常であることを装います0_o。
  4. 入力パラメータに応じて、モデル内でカスタム検証がトリガーされます。




このような要件を持つユーザーモデルにはメールは必須ですか? 回答:いいえ、アプリケーションがなくてもアプリケーションは正しく動作するはずです。



しかし、登録フォームはどうですか?



真実は周りにあります



最初と2番目の状況をよく見ると、フォームはhtmlピース以上のものであることが明らかになります(apiにはちなみにhtmlはありませんが、そこには「フォーム」もあります)。 したがって、パスワードの確認、電子メールの可用性を検証する必要があるのは、特定の状況におけるフォームです この動作はモデルではなく、具体的な表現の特定の形式です。 面白いのは、他の多くのフレームワークにはそのような問題がないことです。 フォームモデルはdjangozend frameworksymfonyyiiにあります。 そして、レールで同様のことをしようとする試みさえあります。 ActiveModelを介してこの機能を実装することもできます。



この全体の話で個人的に私を混乱させるのは、レール開発者自身がこれらの問題を解決する間違った方法を示しているということです。 以下のようなバリデーターを追加します。confirmation=> true、実際の基本的なmvc原則に違反しています。モデルはビューに依存していません。



私たちはプロジェクトの解決策を見つけましたが、これまでのところそれは一般的に私たちに合っており、同時に別のよく知られている問題を解決しています。 特定のフォームについては、モデルの相続人を作成し、実際にそれらを介して作業するという事実にあります。 もちろん、これは最も自然なハックですが、別のフォームを作成しようとして、ネストされたフォームを実装するときに困難に直面し、このビジネスをより良い時期まで延期しました。



1.アプリにtypesフォルダーを作成します。

2. base_type.rbを追加します



module BaseType extend ActiveSupport::Concern module ClassMethods def model_name superclass.model_name end end end
      
      







3.目的のタイプを作成します。 例:



 class UserEditType < User include BaseType attr_accessible :first_name, :second_name validates :first_name, :presence => true validates :second_name, :presence => true end
      
      







そこで、単純な継承を使用して、現在のビューとその要件に応じて、カスタム検証のタスクを解決しました。 確かに、いくつかのgemの結びつきをmodel_nameではなくクラス名に修正する必要があります(たとえば、carrierwaveはクラスに基づいてパスを構築します)が、これまでのところ非常に簡単に解決されています。



なぜフォームではなくタイプと呼ばれるのですか? apiにはそのような形式はありませんが、要件は同じです。 そしてTypeという名前はsymfonyフレームワークから取られています。



最後の例は、attr_accessibleに関連する別の問題が解決されていることを示しています。 もちろん、これをオプションとして使用できると主張することもできますが、実際には、上層に関する情報をモデルに追加することでカプセル化に違反します。



All Articles