Railsでモデルを分割しようと思った時
Rails4から導入されたconcernsを使うという方法もあるが、これは「他のモデルにまたがる処理があるときそれを分割する」場合に使うということらしいので、単純にモデルに色々な処理が入り過ぎたり、重複が沢山あってそれを整理するという場合には適用し辛いのかなと思った。
で、例えばですが、twitterログインやfacebookログインなどを使ってユーザログインさせる処理を書いている場合(userモデルを作って)、provider(twitterやfacebook)毎の登録処理が微妙に似ていたりする。が、一つのメソッドにはしずらい。
そういった場合にif文が多くなるので、userモデルを親クラスとしてtwitter_userやfacebook_userを作って更にfactoryクラス作ってやったら、以外とすっきりした。
もっと良い方法があるのだろうけど、取りあえずこういう方法もあるんだなーという感想
class User < ActiveRecord::Base def self.create_account(auth) @user = UserFactory.create_user(auth[:provider]) @user.create_account(auth) end end
1 class TwitterUser < User 2 3 def create_account(auth) 4 @new_user = User.find_or_create_by(email: auth[:extra][:raw_info][:email]) do|user| 5 user.name = auth[:extra][:raw_info][:name] 6 user.email = auth[:extra][:raw_info][:email] 7 end 8 @provider = AuthProvider.find_or_create_by(provider: auth[:provider], user_id: @new_user.id) do |auth_provider| 9 auth_provider.user_id = @new_user.id 10 auth_provider.uid = auth[:uid] 11 auth_provider.provider = auth[:provider] 12 unless auth[:extra].blank? 13 auth_provider.screen_name = auth[:extra][:raw_info][:nickname] 14 auth_provider.image_path = auth[:extra][:raw_info][:image] 15 end 16 auth_provider.token = auth["credentials"]["token"] unless auth["credentials"].blank? 17 end 18 @new_user.login_provider = @provider 19 20 @new_user 21 end 22 end
1 # coding: utf-8 2 3 class FacebookUser < User 4 5 def create_account(auth) 6 @new_user = User.find_or_create_by(email: auth[:info][:email]) do |user| 7 user.name = auth[:info][:name] 8 user.email = auth[:info][:email] 9 end 10 @provider = AuthProvider.find_or_create_by(provider: auth[:provider], user_id: auth[:user_id]) do |auth_provider| 11 auth_provider.user_id = @new_user.id 12 auth_provider.uid = auth[:uid] 13 auth_provider.provider = auth[:provider] 14 unless auth[:info].blank? 15 auth_provider.screen_name = auth[:info][:nickname] 16 auth_provider.image_path = auth[:info][:image] 17 end 18 auth_provider.token = auth["credentials"]["token"] unless auth["credentials"].blank? 19 auth_provider.save 20 end 21 @new_user.login_provider = @provider 22 @new_user 23 end 24 end
最後にFactoryクラス
1 class UserFactory 2 def self.create_user(provider) 3 if provider == 'facebook' 4 @user = FacebookUser.new 5 elsif provider == 'twitter' 6 @user = TwitterUser.new 7 end 10 @user 11 end 12 end