Ruby on Railsでのオプションの実装がいかに簡単でシンプルか

プロローグ



画像

おそらくすべてのWeb(およびWebだけでなく)開発者は遅かれ早かれ、 ユーザーオプションなどの問題に対処する必要がありました 。 私が言っていることは、写真に表示するのが最も簡単です。 オプションとは、チェックボックスを意味します(つまり、オプションがあるかどうか)。 通常、このようなオプションはあまり多くありません(約2〜10)。 それらは通常、プロファイルの登録および/または編集時に示されます。



問題の声明



原則として、プロジェクトの開発キャンペーンは通常、これらの設定の数(および設定自体)を変えることができるため、これらのオプションのメカニズムを実装して、できるだけコードを変更せずにそれらの追加/変更/削除ができるだけ簡単になるようにすることをお勧めします それを解決する方法と、Ruby on Railsフレームワークの一部としてこの問題を解決した方法を説明します。



実装オプション



一般に、私は通常インタビューでこの質問をします;私は多くの答えを聞きました。 1つは2つのテーブルを使用することです。1つはオプション用、もう1つはユーザーオプション通信用です(レコードがある場合は、フォーム内のチェックマークを意味します)。

利点:

短所:

2番目のポイントについて説明します。次のようなものがあります。



   <%= f.check_box:send_mail_on_friend_request%>


もちろん、これを実装できますが、モデル内のコードは簡単ではありません。



別のオプションは、オプションに1つの列を使用することです-オプションがシリアル化された形式で保存されるテキスト



クラスUser
  シリアライズ:オプション、ハッシュ
終わり


この例では、ユーザーがどのようなオプションを使用できるかは明確ではありませんが、改善します。



クラスUser
   OPTION_1 =:key_1
   OPTION_2 =:key_2

  シリアライズ:オプション、ハッシュ

   def option_1 =(値)
     self.options [:key_1] = value
  終わり
   def option_2 =(値)
     self.options [:key_2] = value
  終わり
   def option_1
     self.options [:key_1]
  終わり
   def option_2
     self.options [:key_2]
  終わり
終わり


すでにわかりやすいが、あまりにも多くの方法:20のオプションがある場合はどうでしょうか? Define_methodはこの問題を完全に解決します(その使用例を以下に示します)。 しかし、考えてみましょう:オプション、それは単なるチェックボックスであり、ほんの少し-コックされるかどうか(はい、はい、女性の直感のように:)、なぜシリアライズ、デシリアライズしますか? 簡単にできますか?



私の実装



そのようなオプションがいくつあるか考えてみましょう。 最大で10、まあ、20、ユーザーがいっぱいになると思います。 しかし、オプションを通常の番号に保存するとどうなりますか? いいアイデアです。ちょっとした作業を覚えておく必要があります。



クラスUser <ActiveRecord :: Base
   NOTIFY_ON_MAIL = 0b0001
   NOTIFY_ON_WALL_POST = 0b0010
   NOTIFY_ON_FRIEND_REQUEST = 0b0100
   NOTIFY_ON_COMMENT_ANSWER = 0b1000

   def notify_on_mail
     self.options&NOTIFY_ON_MAIL!= 0
  終わり

   def notify_on_mail =(値)
     if value!= "0"
       self.options | = const
    他に
       self.options&=〜const
    終わり
  終わり
終わり


いいね これで、任意の数のオプションを一般化できます。



クラスUser <ActiveRecord :: Base
   NOTIFY_ON_MAIL = 0b0001
   NOTIFY_ON_WALL_POST = 0b0010
   NOTIFY_ON_FRIEND_REQUEST = 0b0100
   NOTIFY_ON_COMMENT_ANSWER = 0b1000

   [NOTIFY_ON_MAIL、NOTIFY_ON_WALL_POST、NOTIFY_ON_FRIEND_REQUEST、NOTIFY_ON_COMMENT_ANSWER] .each do | notifer |
     const = self.const_get(notifer)

     define_method notifer.downcase.to_sym do
       (mail_options&const)!= 0
    終わり

     define_method "#{notifer.downcase} ="。to_sym do | flag |
       if flag!= "0"
         self.mail_options | = const
      他に
         self.mail_options&=〜const
      終わり
    終わり
  終わり
終わり


新しいオプションを追加するには、2行だけを変更する必要があります。 うーん、すべてを1つに減らすとどうなりますか? 結果:



クラスUser <ActiveRecord :: Base
   NOTIFY_ON_MAIL = 0b0001
   NOTIFY_ON_WALL_POST = 0b0010
   NOTIFY_ON_FRIEND_REQUEST = 0b0100
   NOTIFY_ON_COMMENT_ANSWER = 0b1000

   constants.grep(/ ^ NOTIFY _ /)。それぞれdo | notifer |
     const = self.const_get(notifer)

     define_method notifer.downcase.to_sym do
       (mail_options&const)!= 0
    終わり

     define_method "#{notifer.downcase} ="。to_sym do | flag |
       if flag!= "0"
         self.mail_options | = const
      他に
         self.mail_options&=〜const
      終わり
    終わり
  終わり
終わり


ビューのフィールドもループで生成できます。

小さなメモがあなたをいくつかの考えに導いたことを願っています:)



All Articles