0

アプリケーションに登録解除機能を追加したいと考えています。それを達成するための最良の方法は何ですか?Boolean 列を追加しようと考えており、その true/false の値に応じてメールを送信しますが、この場合、通知の種類ごとに Boolean 列を作成する必要があります。ハッシュを含む単一の列を作成する方法はありますか?

{:daily_notification=>true, :weekly_notification=>false, :yearly_notification=>true}

前もって感謝します。

4

2 に答える 2

1

登録を解除する必要がある電子メールがたくさんあるため、アプリケーションで次の方法でそれを行っているため、次のYAML formatようにユーザーテーブルに許可ハッシュを保存しています

add_column :users, :permission, :string, :limit=> 500

デフォルトの権限を保存するには

user = User.first
default_permission_hash = {"send_daily_email"=>"true", "send_weekly_email"=>"true", "send_monthly_email"=>"true"}
user.permission = default_permission_hash.to_yaml
user.save

アクセス許可を更新するには

user = User.first
permission_hash = YAML::load(user.permission)
permission_hash["send_daily_email"] = false
user.permission = permission_hash.to_yaml
user.save

モデル内

def is_permission_for?(email)
  permission_hash = YAML::load(self.permission) 
  permission_hash[email] == "true"
end

コントローラ内

user = User.first

if user.is_permission_for?("send_daily_email")
  //send daily email
end
于 2013-04-17T06:14:27.627 に答える
1

Salil の提案に代わるものは、代わりに単一のビットマスクされた列を使用することですsubscription_mask

まず、適切なモデルで配列定数を設定します (仮定User):

# user.rb
SUBSCRIPTION_TYPES = ["Daily", "Weekly", "Monthly"]

この配列の最後にある限り、サブスクリプションの種類を後で追加できます。この 1 つの列に大量のフラグを非常に効率的に格納できます。

次に、仮想属性を使用して、ビットマスクと対話する一連のメソッドを作成できますsubscriptions

# Make subscriptions attr_accessible so we can mass assign to it (useful for forms)
attr_accessible :subscriptions

# Basic setter, overwrites all subscriptions with an array of subscriptions
def subscriptions=(subs)
  self.subscription_mask = (SUBSCRIPTION_TYPES & subs).map{ |s| 2**SUBSCRIPTION_TYPES.index(r) }.inject(0, :+)
end

# Basic getter, returns an array of the set subscriptions
def subscriptions
  SUBSCRIPTION_TYPES.reject do |s|
    ((subscription_mask || 0) & 2**SUBSCRIPTION_TYPE.index(s).zero?
  end
end

# Check if a subscription is set
def has_subscription? (sub)
  self.subscriptions.includes? sub
end

# Add subscriptions to the current mask without affecting any others
def set_subscriptions (*subs)
  self.subscriptions = self.subscriptions | subs
end

# Remove subscriptions from the current mask without affecting any others
def unset_subscriptions (*subs)
  self.subscriptions = self.subscriptions - subs
end

そこにはいくつかの方法がありますが、さまざまな状況で役立つことがわかりました。

これらのメソッドを使用すると、次のようにユーザーのサブスクリプションを設定できます。

@user.subscriptions = ["Weekly", "Monthly"]

そして、次のサブスクリプションがあるかどうかを確認します。

@user.has_subscription? "Daily" # => false, in this case

その同じユーザーが毎日のメッセージを購読していて、毎週のメッセージを購読解除した場合:

@user.set_subscriptions "Daily"
@user.unset_subscriptions "Weekly" # => ["Weekly", "Monthly"]
# Or, to do both changes at once (you need to re-set Weekly though)
@user.subscriptions = ["Weekly", "Monthly"]

このアプローチのもう 1 つの利点は、これをクエリで使用できることです。たとえば、毎週のサブスクリプションですべてのユーザーを取得するには、次のようにします。

User.where("subscription_mask & ? > 0", 2**SUBSCRIPTION_TYPES.index("Weekly"))

少し面倒ですが、メソッドまたはスコープを使用して簡単にクリーンアップできます。

于 2013-04-17T07:19:05.390 に答える