deviseで複数モデルを管理

榊間です。

行けるかどうかわからない語学留学の予定を立てるのが最近の楽しみです。

ということで、今日は新しくアプリを作るなら大体使うであろうdeviseについて書いていこうと思います。
複数の種類のユーザーを想定したときに、viewやmodelを別々にしたいってときがあったので、そのやり方を書いていきます。


devise導入

まずはdeviseを使えるようにします

rails g devise:install

次に/config/initializers/devise.rbで

config.scoped_views = true

にしたら


ここからそれぞれのユーザーに対してmodelとcontrollerとviewを作っていきます。(今回はuserとengineer)

rails g devise user
rails g devise engineer
rails g devise:controllers users
rails g devise:controllers engineers
rails g devise:views users
rails g devise:views engineers


あとはroutingを

devise_for :users, controllers: {
  sessions:      'admins/sessions',
  passwords:     'admins/passwords',
  registrations: 'admins/registrations'
}
devise_for :engineers, controllers: {
  sessions:      'users/sessions',
  passwords:     'users/passwords',
  registrations: 'users/registrations'
}

として、コントローラーをしっかり分けたらOK
ここ参考にしました
Ruby - Railsでdeviseひとつで複数モデルを管理しよう - Qiita(知ってる人の記事を知らず知らずのうちに参考にしてました、、、)

本当はここからそれぞれにomniauthを導入したかったんですが、長くなりそうなのでまた今度にします!

ブロックの代わりに(&:hoge)を使ってみる

榊間です。

明日ある大学のテストに怯えながら書いてます、、、

今日はrubyの仕組み的な話です。


(&:)ってなに....

この前作業してたら、

Article.where(user: current_user).map{|e| e.id}

みたいな記述を、

Article.where(user: current_user).map(&:id)

に直してもらいました。なぜこんな風に書けるのか、、、


Article.where(user: current_user).map{|e| e.id}をArticle.where(user: current_user).map(&:id)に変化させていきます

Kernelのsendメソッド使います。第1引数にシンボル化したレシーバのメソッドをとり、第2引数以降はレシーバの引数をとります。

Article.where(user: current_user).map { |e| e.send(:id) }


それから&lambdaを使って、ブロックをオブジェクトにします。ブロックをmapの引数として渡せるようになります。

Article.where(user: current_user).map(&lambda { |e| e.send(:id) })


作ったオブジェクトを、メソッドとして定義します。(シンボル化したレシーバのメソッドをオブジェクトの変換するメソッド

class Symbol
    def to_proc
      lambda { |e| e.send(:id) }
    end
  end

Article.where(user: current_user).map(&:id.to_proc)


&を設置しているのでrubyはオブジェクトを&の後に要求しますが、シンボルじゃんってなって、to_procメソッドを勝手に送ります。

class Symbol
    def to_proc
      lambda { |e| e.send(:id) }
    end
  end

Article.where(user: current_user).map(&:id)


実際は

class Symbol
    def to_proc
      Proc.new { |*args| args.shift.__send__(self, *args) }
    end
  end

が記述されているので、Article.where(user: current_user).map(&:id)の記述だけで済むみたいですね、、、

参考にしたのはここRubyのSymbol#to_procを考えた人になってみる


うーん、理解しきるのが難しい、、、

初めてのルーティング

榊間です。

なぜ週一回投稿すると言ってしまったのかじわじわ後悔しています(2回目にしてネタ切れ)

とりあえず今回は、1回目に悩みすぎてact-as-taggable-onという謎の選択をしてしまったので、rails初心者っぽくルーティングについて書いていこうと思います。


ルーティング

インターンするまでに少しだけrailsをやっていたんですが、そのとき知っていたルーティングの書き方はこれだけ

resources :articles
get '/articles/:id' => 'articles#show'

んで、インターンを初めてサービスのコードを見せてもらったときに、ルーティング予想以上に訳がわからなくて驚きました。(namespace? collection? なぜdoとendが...)

それで調べてみたら、いろいろな書き方があったのでまとめて書こうかと思います。


ネストの概念

resources :users do
resources :articles
end

とかすると、resources :usersに加えて、usersのidごとにresources :articlesが展開されるイメージ。例えばarticles#index
prefix...users_articles_path
フルパス.../users/:users_id/articlesになります。


namespace

これはグループ化に使います。

namespace :user do
resources :articles
end

こうすることで、
prefix...user_articles_path
フルパス.../user/articles
controllerのaction...user/articles#indexになります。(indexの場合)


collection

基本の7つのルーティング(index,show,new,create,edit,update,destroy)以外のものを追加したいときに使います

resources :users do
collection do
get :article
end
end

prefix...article_users_path
フルパス.../users/article
controllerのaction...users#articleになります。prefixはusersの方が後になります。


member

collectionと基本は同じですが、

resources :users do
member do
get :article
end
end

prefix...article_user_path
フルパス.../users/:id/articleになります。collectionに対して、userのidごとのarticleを動かせるようになります。


まだまだたくさんオプションとかもありますが、よく見るやつを書きました!
参考にしたのはルーティングを極める (後編) | TechRacho

今度はもっと実のある記事を書こうと思います...m(__)m