0

これをローカルでテストしています。私のIPは127.0.0.1. ip_permissions テーブルが空です。サイトを閲覧すると、すべてが期待どおりに機能します。

ここで、禁止された IP でサイトを閲覧することをシミュレートしたいと考えています。したがって、次の方法で IP を ip_permissions テーブルに追加します。

IpPermission.create!(:ip => '127.0.0.1', :note => 'foobar', :category => 'blacklist')

Rails コンソールで、次の方法でキャッシュをクリアします。Rails.cache.clear. サイトを閲覧します。に送信されませんpages#blacklist

サーバーを再起動すると。サイトを閲覧すると、 に送られpages#blacklistます。ip_permissions テーブルが更新されるたびにサーバーを再起動する必要があるのはなぜですか? キャッシュに基づいてフェッチするべきではありませんか?

ルートは次のようになります。

class BlacklistConstraint
  def initialize
    @blacklist = IpPermission.blacklist
  end

  def matches?(request)
    @blacklist.map { |b| b.ip }.include? request.remote_ip
  end
end

Foobar::Application.routes.draw do
  match '/(*path)' => 'pages#blacklist', :constraints => BlacklistConstraint.new
  ....
end

私のモデルは次のようになります。

class IpPermission < ActiveRecord::Base
  validates_presence_of :ip, :note, :category
  validates_uniqueness_of :ip, :scope => [:category]
  validates :category, :inclusion => { :in => ['whitelist', 'blacklist'] }

  def self.whitelist
    Rails.cache.fetch('whitelist', :expires_in => 1.month) { self.where(:category => 'whitelist').all }
  end

  def self.blacklist
    Rails.cache.fetch('blacklist', :expires_in => 1.month) { self.where(:category => 'blacklist').all }
  end
end
4

1 に答える 1

2

開始時に一度だけロードされるルートファイルでBlacklistConstraintを初期化しています。そこで、IpPermission.blacklistを呼び出し、それをインスタンス変数に格納します。Initializeはもう呼び出されないため、同じレコードに対してチェックします。

レコードを更新する場合は、リクエストごとにレコードをロードする必要があります。

class BlacklistConstraint
  def blacklist
    IpPermission.blacklist
  end

  def matches?(request)
    blacklist.map { |b| b.ip }.include? request.remote_ip
  end
end
于 2012-11-09T10:58:16.923 に答える