【Rails3.2】deviseを触ってみた

最近DSLとかばかり見ているのでたまにはプログラミングもせなあかんということで、Railsを復習がてらアプリを作成することにしました。

そこで、IDとパスを使った認証が必要になりそうだったのでdeviseというgemを使って色々やってみたのでそれの記録です。

deviseとは

gem上で使えるサインアップ、ログイン、ログアウトの仕組みを作ってくれるgemです。これを使ってモデルを作るだけで勝手にログイン画面とかを作ってくれます。

Railsでdeviseを使う

実行環境

今回はの実行環境は以下。

  • Rails 3.2.16

  • Ruby 2.0.0p481

インストール

Railsでdeviseを使うためにはGemfileに次の行を書き加えます。

/Gemfile

gem 'devise'

後に、bundle installをする。後に、関係ファイルをジェネレート。

$ bundle install
$ rails g devise:install # config/devise.rb(設定ファイル)の作成をします。

また、deviseをログインしていない状態でログインしないと入れないアクションを実行しようとした時rootにリダイレクトするのでテキトウにrootをroutes.rbに書いておきます。

/config/routes.rb

  root :to => "home#index" # home/indexをルートにする

モデルを作る

これで使う準備ができたので、deviseを使ってモデルを作成します。railsプロジェクトのルート上で以下コマンドを実行。

$ rails generate devise User
$ rake db:migrate

Userは任意のモデル名です。まあ、普通ログインシステムを作る時必要なのはユーザの情報なのでUserが一般的でしょう。

このコマンドを実行するとdevise用のモデルが作成されます。その後マイグレートしてあげましょう。

警告用のビューを足す

警告を全てのページに表示ができるようにlayoutsを編集しましょう

/app/views/layouts/application.html.erb

<p class="notice"><%= notice %></p>
  <p clss="alert"><%= alert %></p>
<%= yield %>

yieldの前に置いておくのが一番自然だと思われます。

ルーティング

rake routesを実行すると以下の様なルーティングになっています。

                    root        /                              home#index
        new_user_session GET    /users/sign_in(.:format)       devise/sessions#new
            user_session POST   /users/sign_in(.:format)       devise/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)      devise/sessions#destroy
           user_password POST   /users/password(.:format)      devise/passwords#create
       new_user_password GET    /users/password/new(.:format)  devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format) devise/passwords#edit
                         PUT    /users/password(.:format)      devise/passwords#update
cancel_user_registration GET    /users/cancel(.:format)        devise/registrations#cancel
       user_registration POST   /users(.:format)               devise/registrations#create
   new_user_registration GET    /users/sign_up(.:format)       devise/registrations#new
  edit_user_registration GET    /users/edit(.:format)          devise/registrations#edit
                         PUT    /users(.:format)               devise/registrations#update
                         DELETE /users(.:format)               devise/registrations#destroy

このアクションのURLを直接入力することでログイン、サインアップなどのフォームが出現します。ビューも勝手にできているようです。

ビューを編集できるようにする

ビューは初期状態では内部で処理されてしまっていますのでカスタマイズをするためにapp/viewに出しておいたほうが懸命です。以下コマンドで出力されます。

$ rails generate devise:views users

後に、devise.rbの208行目にあるconfig.scoped_viewsのコメントアウトを外し、trueにしてしまいましょう。

/config/devise.rb

  # ==> Scopes configuration
  # Turn scoped views on. Before rendering "sessions/new", it will first check for
  # "users/sessions/new". It's turned off by default because it's slower if you
  # are using only default views.
  config.scoped_views = true

ログインしないとできないページを作る

アクションのコントローラの先頭ににbefore_filterを追加します。

/app/controllers/user_controller.rb

  before_filter :authenticate_user!, :except => [:show, :index]

  class UsersController < ApplicationController
  def index
  …

:exceptパラメータで認証なしで実行可能なアクションを指定可能です。

ログイン方法をe-mailからユーザネームに変更する

ログイン方法がデフォルトではe-mail、パスの入力になっています。これを例えばユーザネームとかに変更したい場合の対処法。

とりあえずモデルに変更するカラムを足す。今回はusernameというカラムを足していきます。

$ rails g migration add_username_to_users username:string
$ rake db:migrate

次に、付け加えたカラムを認証用のキーに変更します。所謂、「主キー」の変更ですね。devise.rbの32行目config.authentication_keysを書き換えます。

config/devise.rb

 # config.authentication_keys = [ :e-mail ]
 # ↓
 config.authentication_keys = [ :username ]

このdevise.rbではdeviseの様々な設定ができるので覚えておいたほうが良いですね。

あとはビューをいじります。
emailを入力するべきところをすべてusernameを入力するように変更しましょう。とりあえずは、/app/views/users/sessions/new.html.erbと/app/views/users/registrations/new.html.erbを変更すればサインアップとサインインはできるようになります。コードは省略。

これでうまくいくかなーとおもいきや、e-mailを入れろと怒られます。バリデーションの回避がうまく行っていないようです。
以下のメソッドをUserモデルに付け加えましょう。

/app/model/user.rb

  def email_required?
    false
  end

これでバリデーションを無視することが出来ました。本当はe-mailカラムを削除しておかないといけませんが、まあとりあえずはこれで変更が可能ですね。e-mailは後で任意で入れさせるようにするかもしれないので今回は放っておきます。

参考

 

【Ruby】Clockworkを触ってみた

Ruby on Railsは基本的にはユーザの入力を受け取ってDBを操作、表示するのが主な仕事だと思ってるんですがどうしても定時処理が必要なことは多いと思います。

自分は予め用意されたDBをもとに一定時間ごとにDBの内容をTweetするような定時処理を作ってやりたいのですがcronにスクリプトを書いて直接DBをいじるのはやり方がよくわからない・・・ということでRubyのgemにClockworkというモノがあるらしいので少し触ってみました。諸サイトによると「Rubyのcronっぽいやつ」らしいです。

参考

今回ちろっとしか触ってないので詳しい説明はこっちのがよっぽどよい。

Qiita/Clockwork Cheat Sheet http://qiita.com/ogomr/items/27e9fc7af5b978b5ced6

Clockwork本家 https://github.com/tomykaira/clockwork

準備

とりあえずgemでclockworkをインストールしましょう。

$ gem install clockwork

最新版は0.7.7みたいです。

テスト

とりあえずどこでもいいので適当なrubyファイルを作成しましょう。ここではclock.rbとしてます。

まずは、clockworkをrequireしてあげてClockworkというモジュールを作ります。
後に、handlerというメソッドが提供されていますのでイテレータを使って呼び出すようです。(この辺がRuby不勉強で不明…

後に、everyというメソッドをhandlerのあとに呼び出してどういう間隔で処理を行うか、を指定します。
このeveryのあとにdoをつけてブロックをつけてあげると下のようにhandlerを使わなくても簡単に処理を書くことができます。

every(5.second, 'hoge.job') do
    p "Running!"
end

これを元になんとなくこんな感じで書いてあげると5秒毎に「second_job」という自作のメソッドを実行します。

require 'clockwork'

def second_job
	p "method_print"
end

module Clockwork

  handler do |job|
	case job
	when 'hoge.job'
		second_job
	end
  end

	every(5.second, 'hoge.job')

end

実行

実行をフォアグラウンドで実行してみる。

$ clockwork clock.rb

 

でおk。ログを残しながら実行をしてくれます。

ただし、通常はバックグラウンドでの実行が主になると思いますのでそのへんをまた研究が必要そうです。やり方自体は参考サイトを見よう。