KEMBAR78
My sql viewに救われる(かもしれない) | PPTX
MySQL VIEWに
救われる(かもしれない)
森
自己紹介
森
新卒3年目/ferret
t:@5m0_0m
最近の楽しみ:野菜の育ち具合を眺める
Railsでログイン認証を実装
Railsでログイン認証を実装
通常であればさくさく実装できるもの
→既存DBを使う場合(deviseのカラム名と合わない場合)とても大変
→オーバーライドの嵐
→つらい
→思わぬところではまる
→つらい
Railsでログイン認証を実装
通常であればさくさく実装できるもの
→既存DBを使う場合(deviseのカラム名と合わない場合)とても大変
→オーバーライドの嵐
→つらい
→思わぬところではまる
→つらい
deviseで扱いやすいカラム名
であればつらくない?
MySQLのviewをつかう
view
テーブルから一部を取り出したものに名前を付け、
あたかも独立したテーブルのように扱うようにした
もの (DBOnline)
members
実際のtable
users
membersの
view
MySQLのviewをつかう
members
実際のtable
users
membersの
view
Web1
データ更新
実際のtableも更新
Web2
例えばこんなテーブル
Field Type Null Key Default Extra
uid int(11) NO PRI NULL auto_increment
email_address varchar(255) NO UNI
passwd varchar(255) NO
reset_password_token varchar(255)
・・・省略・・・
members
例えばこんなテーブル → viewをつくる
Field Type Null Key Default Extra
id int(11) NO 0
email varchar(255) NO
encrypted_password varchar(255) NO
reset_password_token varchar(255)
・・・省略・・・
users
viewの作成
class CreateUsersView < ActiveRecord::Migration
def self.up
execute "CREATE VIEW users(id, email, encrypted_password, reset_password_token,
reset_password_sent_at <省略>) AS SELECT * FROM members;"
end
def self.down
execute "DROP VIEW users;"
end
end
migrationファイルを用意して $ rake db:migrate:up VERSION=xxxxxx
参考:RailsでMySQL VIEWを使うには?
ただし
auto_incrementではまる
ユーザ登録完了後、ログイン状態にならない問題
ユーザ登録(registrations_controller / resource.save)は問題ないのにログインできない
=> #<User id: 0, email: "test@basicinc.jp", encrypted_password: "$2a$11$VjI5iWn...", ・・・省略・・・>
=> #<User id: 0, email: "test@basicinc.jp", encrypted_password: "$2a$11$VjI5iWn...", ・・・省略・・・>
→save前のresourceを確認
→ 「id: 0」?
→ そのままresource.save。通常ならこの時点でidが設定される。
→「id: 0」!
viewのデフォルト値が0になっている
Field Type Null Key Default Extra
uid int(11) NO PRI NULL auto_increment
email_address varchar(255) NO
・・・省略・・・
Field Type Null Key Default Extra
id int(11) NO 0
email varchar(255) NO
・・・省略・・・
users
members
インスタンス生成時にidを修正して対応
idとして0がすでに入っている状態なので、view上では id:0 のユーザが作成されている状態
→実際のテーブルにはidが+1された状態で保存されているので、データとしては問題ない
コールバックのafter_initializeを使ってidをnilにする
参考:ActiveRecordでMySQLのviewに対してinsertする
class User < ActiveRecord::Base
self.primary_key = :id
self.table_name = "users"
after_initialize :fix_id
def fix_id
self.id = nil if self.id == 0
end
end
まとめ
- viewを使うことで救われそうな気がする
- viewは結合したテーブルで使われる例がよくあるので、今回以外でも救われるケ
ースは多々ありそう
- 困ったらライブラリの中を見ると良いことがある(かもしれない)
- 疲れたときはSidekiqの顔文字メソッドを眺める
- TheHiveProjects/rails_sql_viewsというgemもある(ただしRails3)

My sql viewに救われる(かもしれない)