あなたは宝石を必要としません-あなたはこれをするためにちょっとしたヘルパーを書くことができます。
ApplicationControllerで:
def force_ssl(options = {})
host = options.delete(:host)
unless request.ssl? or Rails.env.development?
redirect_options = {:protocol => 'https://', :status => :moved_permanently}
redirect_options.merge!(:host => host) if host
flash.keep
redirect_to redirect_options and return
else
true
end
end
そして、あなたのコントローラーで:
before_filter :force_ssl, :only => [:login]
これは、パスヘルパーでhttpsプロトコルを自動的に選択するという2番目の要件を満たしていませんが、ルートヘルパーはコントローラーレベルで何が起こっているかを気にしないため、コントローラー指定のSSL強制では達成できません。ルートがHTTPSを指定している場合、HTTPS以外のURLをコントローラーアクションに解決しないため、これは実際にはコントローラー強制SSLと相互に排他的です。つまり、force_ssl
フィルターがヒットすることはありません。ただし、ルーティングを複製して、HTTPSスコープのルートとスコープなしのルートの両方を作成し、スコープなしのルートをHTTPSスコープのルートの前に定義して、HTTPSスコープのバージョンがヘルパー名を引き継ぐようにすることでこれを実現できます。ただし、これは重複を意味します。
ただし、少しのヘルパーメソッドでそれを達成できる場合があります。私はこれをテストしていませんが、概念は機能するはずです:
def route_with_https_preference(&block)
&block.call
scope :protocol => 'https://', :constraints => { :protocol => 'https://' } do
instance_eval &block
end
end
route_with_https_preference do
resources :gizmos do
resources :widgets
end
end
ルートファイルでSSLスコープのルーティングを簡単に実現できます(詳細については、この回答を参照してください)が、プロトコルスイッチには完全修飾URLが必要なため、_url
ヘルパーではなくヘルパーを使用する必要があります。_path