rails でログイン認証されていない場合にログイン画面へ遷移させる方法(と、Active Admin を利用して管理画面を作成する際に除外する方法)
ログイン認証チェックを全画面に対応させる
./app/controllers/application_controller.rb
に以下の様な形で認証チェックを入れます。
# ./app/controllers/application_controller.rb class ApplicationController < ActionController::Base before_action :user_logged_in? def user_logged_in? if session[:user_id] begin @current_user = User.find_by(user_id: session[:user_id]) rescue ActiveRecord::RecordNotFound reset_user_session end end return if @current_user # @current_userが取得できなかった場合はログイン画面にリダイレクト flash[:referer] = request.fullpath redirect_to login_index_path end def reset_user_session session[:user_id] = nil @current_user = nil end end
まず、before_action :user_logged_in?
の部分ですが、これでどのコントローラが呼び出された時でも、user_logged_in?
メソッドが呼び出されることになります。
で、user_logged_in?
では、認証情報の有無を確認することでログインしている場合とログインしていない場合の処理を分岐させます。
(上記の例ではsession[:user_id]
を認証情報として利用しています。)
このままだと、ログイン画面でもこのチェックが行われてしまうため、ログインコントローラは除外する必要があります。
それは./app/controllers/login_controller.rb
に以下のように追記します。(login_controller.rb
は、名前はもちろん任意です。)
# ./app/controllers/login_controller.rb class LoginController < ApplicationController skip_before_action :user_logged_in? <-この部分を追記 ・・・ end
これにより、ログインコントローラ内では、認証チェックがスキップされます。
Active Admin で除外するには
で、今回、Active Admin という管理画面系のgemを利用したのですが、なにも考えずに導入したら、Active Admin が生成する管理者ログイン画面を表示する際にも、認証チェックが発生してしまって、利用者ログイン画面が表示されました。
これはまずいので、Active Admin 側では、ログイン画面と同じように認証チェックをスキップしたいと考えました。
application.rb
に認証チェックを入れるのではなく、個々のコントローラに認証チェックを入れれば解決するのですが、それは今後コントローラが追加されることを考えるとうまい解決にはなりません。
で、結局どのようにするか。
ActiveAdmin にはコンフィグが用意されているのですが、このコンフィグ(./config/initializers/active_admin.rb
)内に以下のように追加します。
# ./config/initializers/active_admin.rb ActiveAdmin.setup do |config| ・・・ end ActiveAdmin::BaseController.class_eval do skip_before_action :user_logged_in? end
これで Active Admin 内では認証処理を行わなくなるため、 Active Admin 側の別の認証処理に認証を任せることができます。
[参考] 管理画面系gem administrate
今回の案件で管理画面が必要になり、改めて管理画面系の gem を探してみたところ、 administrate という gem が見た目シンプルでよさそうだったのですが、時間がなかったため今回は利用経験のあった Active Admin を使うことにしました。
時間ができた時に使ってみたいと思います。
ruby の eachメソッドでループ回数(インデックス)が必要な場合 (for文のiのような)
each するときに、ループ回数を利用したい
C言語とかで
for (i=0; i >10; i++) { ... }
とかやると思いますが、このループ変数 i を利用したい時がありますよね。
ruby だとどうするのがいいのか、わかっていなかったので調べてみました。
結果、rubyには便利なメソッドが用意されていました。
each_with_index
このメソッドはインデックスを振ってくれますので、これを利用して以下のように書けばうまくループ回数が利用できます。
tests.each_with_index do |test, i| puts "#{(i + 1)} : #{test.to_s}" end
=> 1 : test1 2 : test2 3 : test3 4 : test4 5 : test5
ここで、i+1 としているのは、インデックスは0から開始されるためです。
each.with_index()
じゃあ、インデックスの開始を指定できないの? ということで上記のように each に with_index() というメソッドをつなげると実現できます。
その場合、以下のように記載すればいいです。
tests.each.with_index(1) do |test, i| puts "#{i} : #{test.to_s}" end
fields_for の際に、インデックスを取得する
上記のような場面と似たような話で、Railsのform_forを利用している際に、更に fields_for を利用する場合、
= f.fields_for :test do |t| = t.index
とすると、インデックスを取得できます。
使い所はあまりないかもしれないですけど、ループさせるようなときには、意外と回数がほしいことがあるので、参考までに。
rails における enum型の注意点
当たり前の話なのかもしれませんが、rails アプリで enumを使用した際にハマったので、備忘として記載します。
前提
enum_helpをインストールしています
(試していませんが、enum_helpを導入していないと、そもそもviewでうまく呼び出せないとか)
参考 : ActiveRecord::Enum の使いドコロ - Qiita
enumはintegerで宣言すること
これ、stringで宣言してenum利用していたんですが、そうすると、登録は可能なんです。
でも、DBから取得する際にnilが返却されます。
しばらくの間なにが原因かわからなくて、時間を浪費してしまいました。
開発環境だったので、sqliteを利用していたのですが、sqliteの仕様かも、と疑ったりして。
なんのことはない、自分の宣言が正しくなかったという。。
ruby の環境更新(アップデート)の手順まとめ
なんで更新?
利用しているPCは1年半くらい利用しており、ごちゃごちゃしてきていました。
今回、新しいWebサイト開発に着手するに当たり、環境を整理したくなりました。
前提
CUIアプリケーションはhomebrewで管理しています。
(GUIアプリケーションはhomebrew caskで管理していますが、今回の更新は対象としていません。)
rubyはrbenvでバージョン管理しています
HOMEBREWの更新とrbenvのバージョン確認
brew自体のアップデートを行います
$ brew update
brewでインストールしたアプリケーションのアップデートを行います
$ brew upgrade
インストールしたアプリケーションのアップデート後の無駄な内容を綺麗にします
$ brew cleanup
rbenvのバージョンを確認します
$ rbenv --version
rubyの更新と更新バージョンへのグローバル環境指定
rbenvでrubyの最新安定版を検索し、該当のバージョンをインストールします
$ rbenv install $(rbenv install -l | grep -v - | tail -1)
上記コマンドでインストールした最新安定版をrubyのグローバル環境で利用するバージョンに指定します
$ rbenv global $(rbenv install -l | grep -v - | tail -1)
rubyのバージョンを確認します
$ ruby -v
ruby_gemsの更新
ruby_gemsのアップデートを行います
$ gem update --system
ruby_gemsでインストールしているパッケージのアップデートを行います
$ gem update
上記コマンドでアップデートしたパッケージにより不要となった内容を綺麗にします
$ gem cleanup
ruby_gemsでインストールしているパッケージのリストを表示し、バージョンを確認します
$ gem list
おわりに
上記で久しぶりにrubyの環境を更新しました。
たまにしか実施しないため、やるたびにやり方を調査するため、備忘として残しておきます。
テンプレートエンジン hamlとslimの比較
一年くらい前に、railsを利用したとある業務アプリケーションの開発において、テンプレートエンジンを比較してhamlを導入しました。
その際に候補として挙がったのが、hamlとslimでした。
いろいろ比較して結果hamlを導入することに決定し、その業務アプリケーションは開発を行いました。
特に問題なく導入することもでき、楽にviewをかけるようになったので、なにも問題なかったのですが、現在、別のRailsアプリケーションに対して、テンプレートエンジンを導入しようとなりまして、そこで改めて、slimが候補に挙がってきました。
しかしながら、過去にどういう経緯でslimではなく、hamlを選択したのか、記録に残っていなかったため、改めて比較検討することにしました。
改めて、hamlとslimを比較 ( +で hamlit と faml も)
少しばかり調べてみたところ、hamlの性能改善を目的としたgemとして、hamlit と faml というテンプレートエンジンもあるようです。
Slimより高速なHaml実装「Hamlit」をリリースしました - k0kubun's blog
faml と slim、hamlit のパフォーマンスの差 - eagletmt's blog
なので、これらを比較対象として検討します。
私が導入を検討する際にまずすることはrubygemsでのDOWNLOAD数とVERSIONSの確認です。
DOWNLOAD数が多いgemは情報も豊富なことが多いですし、VERSIONSで更新の頻度や最終の更新が確認できます。
これらが芳しくないと、導入した後で後悔が待っています。。
上記は現状、以下の様な数字でした。
([2016/11/7 追記] バージョンの日付に誤りがあったため、2016/11/7現在の数字にアップデートしました。 hamlitがかなりDL数を伸ばしています)
gem名 | DOWNLOAD | VERSIONS |
---|---|---|
slim-rails | 2,380,844 | 3.1.1 - August 29, 2016 (11 KB) |
haml-rails | 7,389,426 | 0.9.0 - March 11, 2015 (13 KB) |
hamlit | 250,278 | 2.7.5 - October 15, 2016 (69 KB) |
faml | 33,943 | 0.8.1 - February 27, 2016 (70.5 KB) |
harmit と faml については、性能はいいようなのですが、DOWNLOAD数がそこまで多くないため、個人で利用する分には良さそうだったのですが、今回は除外することにしました。
そこで改めて haml と slim を見てみると、実はhamlのほうが、DOWNLOADは多いけど、更新は止まっているみたいです。
さくっと最終更新とDOWNLOAD数で決めちゃえばいいと思っていましたが、もう少し深く調査する必要がありそうです。。。
haml と slim の性能比較
で、性能比較はというと、上に挙げた hamlit と faml の記事でも分かる通り、slimのほうがかなりいい(というか、hamlが遅い?)ということがわかりました。
ここで、slimのほうが良さそうという感じになったのですが、そうなると、なんで以前の検討でhamlを選んだのか。
どうしてもその時hamlを選択した理由がわかりません。。。
とはいえ、改めて調べてみて、特にslimに問題があるわけでもなさそうだったので、今回のプロジェクトには slim を利用したいと思います。
導入してみて気になったことがあれば別に書きます。