2008年02月13日
■[mysql][mac]mysqlのGRANTやって、ついでにGUIのツールを入れておく
rootと同じ権限
mysql> GRANT ALL PRIVILEGES ON *.* TO user@"%"
-> IDENTIFIED BY 'パスワード' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO user@localhost
-> IDENTIFIED BY 'パスワード' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
参考
http://www.bitscope.co.jp/tep/MySQL/quickMySQL.html
ついでにmysqlのGUIのツールも入れておく
http://dev.mysql.com/downloads/gui-tools/5.0.html
でダウソ
querybrowserでつなぐとき、localhostだとおこられた
127.0.0.1だとつながった。
■[rails]rails2.Xでscaffoldで/admin/usersとかのコントローラ作りたいとき
rails2でscaffoldすると、migrateも作られるようになったのはわかった。
で、usersがある状態で/admin/usersみたいな会員管理コントローラを作りたいとき。
#いや、管理ページはRestfullにする必要ないかもしれないけど。。/mypage/xxxとかありうると思うから
scaffold
$ script/generate scaffold Admin::user --skip-migration
create app/models/admin
create app/controllers/admin
create app/helpers/admin
create app/views/admin/users
create app/views/layouts/admin
create test/functional/admin
create test/unit/admin
create app/views/admin/users/index.html.erb
create app/views/admin/users/show.html.erb
create app/views/admin/users/new.html.erb
create app/views/admin/users/edit.html.erb
create app/views/layouts/admin/users.html.erb
identical public/stylesheets/scaffold.css
dependency model
exists app/models/admin
exists test/unit/admin
create test/fixtures/admin
create app/models/admin/user.rb
create test/unit/admin/user_test.rb
create test/fixtures/admin_users.yml
create app/controllers/admin/users_controller.rb
create test/functional/admin/users_controller_test.rb
create app/helpers/admin/users_helper.rb
route map.resources :users
で、localhost:3000/admin/usersにアクセスすると
NoMethodError in Admin/users#index Showing admin/users/index.html.erb where line #7 raised: You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil.each Extracted source (around line #7): 4: <tr> 5: </tr> 6: 7: <% for user in @users %> 8: <tr> 9: <td><%= link_to 'Show', user %></td> 10: <td><%= link_to 'Edit', edit_user_path(user) %></td>
/admin/user/index.html.erbの7行目に文句言われる
<% for user in @users %>
コントローラーを見ると
def index @admin_users = Admin::User.find(:all) respond_to do |format| format.html # index.html.erb format.xml { render :xml => @admin_users } end end
indexメソットだけ@admin_usersになってるので@usersに戻す。
view直す
<%= link_to 'New user', new_user_path %>
は多分:name_prefix=adminということだから
<%= link_to 'New user', new_admin_user_path %>
xmlの整形でコケル
admin/users.xmlとかでエラーになる
users = Admin::User.find(:all) #中略 format.xml { render :xml => @users }
だと
#<Admin::User id: 1, name: "hogehoge", created_at: "2008-02-12 23:14:05"(略)
<admin/usre id:(略
みたいにしてパースエラーになるのでAdmin::Userモデルはクビでいいと思う。
そもそも同じスキーマに複数モデルがあったらきっと美しくない気がしてきた。
ので、Admin::User.newとかを全部User.newとかにする。
たぶん
これで、ふつーのscaffoldした感じと同じになる気がする。
つまり/admin以下にコントローラを作る場合
- scaffoldする
- route.rbにnamespace書く
- 生成されたcontorollerの
- indexの@admin_usersを@usersにする
- Admin::Users.new等をUsers.newにする
- /models/admin/user.rbを消す
- 生成されたviewの
- migrationをskipしてるのでスキーマ情報がないので書く
- new_user_pathとかをnew_admin_user_pathとかに書き換える
くらいでおkかな。
全部試してないけど。
参考
Rails2.0のRouting(config/routes.rb)の記述方式についてのまとめ。 - RAILS PRESS
大場寧子のホームページ - モジュール下のコントローラをRESTfulにする
大場寧子のホームページ - コントローラをRESTfulにする
大場寧子のホームページ - コントローラのRESTfulインターフェースをカスタマイズする
大場寧子のホームページ - 親子構造のあるモデルを扱うコントローラをRESTfulにする
Ruby On Rails ピチカート街道 - Rails 2.0・その1(RESTful なコントローラのメソッド追加) -
Ruby On Rails ピチカート街道 - Rails 2.0・その3(map.resources の has_one が扱いやすく) -
■[rails][rails]認証。acts_as_authenticatedとrole_requirementとopenid_login_generatorで、両対応な感じを目指す。
acts_as_authenticated
インスコ→じぇねる→migrate
$ ./script/plugin install acts_as_authenticated $ ./script/generate authenticated user account $ rake db:migrate
で、おk
role_requirement
インスコ→じぇねる→migrate
$ script/plugin install http://rolerequirement.googlecode.com/svn/tags/role_requirement/ $ script/generate roles Role User $ rake db:migrate
モデル書く
app/models/role.rb
class Role < ActiveRecord::Base has_and_belongs_to_many :users end
ロールの管理をscaffold
ruby script/generate scaffold role --skip-migration
migrationをskipしてるからか、スキーマ情報が
入ってないのでviewを直す。
(略)
openid_login_generator
既にgemでインスコしてあって、ジェネレータも直してる状態で、
generate
Userモデルはもうあるのでその辺はnで
$ ./script/generate openid_login openid
create lib/openid_login_system.rb
create app/controllers/openid_controller.rb
create test/functional/openid_controller_test.rb
create app/helpers/openid_helper.rb
overwrite app/models/user.rb? (enter "h" for help) [Ynaqdh] n
skip app/models/user.rb
overwrite test/unit/user_test.rb? (enter "h" for help) [Ynaqdh] n
skip test/unit/user_test.rb
overwrite test/fixtures/users.yml? (enter "h" for help) [Ynaqdh] n
skip test/fixtures/users.yml
create app/views/layouts/scaffold.html.erb
identical public/stylesheets/scaffold.css
create app/views/openid
create app/views/openid/welcome.rhtml
create app/views/openid/login.rhtml
create app/views/openid/logout.rhtml
create README_LOGIN
usersにopenid_urlカラムを追加
$ ruby script/generate migration add_column_users_openid_url
exists db/migrate
create db/migrate/003_add_column_users_openid_url.rb
migarate_fileを編集
class AddColumnUsersOpenidUrl < ActiveRecord::Migration def self.up add_column :users, :openid_url, :string end def self.down remove_column :users, :openid_url end end
migrate
$ rake db:migrate (in /home/coek/dev/rails/auth_and_open_id_test) == 3 AddColumnUsersOpenidUrl: migrating ======================================= -- add_column(:users, :openid_url, :string) -> 0.0417s == 3 AddColumnUsersOpenidUrl: migrated (0.0439s) ==============================
モデル書き足す
def self.get(openid_url) find_by_openid_url(openid_url) end
protected validates_uniqueness_of :openid_url, :on => :create validates_presence_of :openid_url
で、controllerとかを
http://d.hatena.ne.jp/crimaru/20080212/1202793189
http://d.hatena.ne.jp/crimaru/20080212/1202812083
とかでやったように全部直す。
validateでコケる
今回はopenidからのログイン(登録)の場合は、idとopenid_urlだけ入れるってのでいいかなと思ってる。
で、普通にサインアップしたときは、openid_urlがNULLでいいかな、と。
なので
validates_presence_of :login, :email
だと、openidから使うときダメになるので
Userモデルに
def openid? self.openid_url.blank? #入ってたらfalseが返る end
なのを書き足して、
validates_presence_of :login, :email, :if => :openid? validates_presence_of :password, :if => :password_required? validates_presence_of :password_confirmation, :if => :password_required? validates_length_of :password, :within => 4..40, :if => :password_required? validates_confirmation_of :password, :if => :password_required? validates_length_of :login, :within => 3..40, :if => :openid? validates_length_of :email, :within => 3..100, :if => :openid? validates_uniqueness_of :login, :email, :case_sensitive => false, :if => :openid? (中略) validates_uniqueness_of :openid_url, :on => :create, :unless => :openid? validates_presence_of :openid_url, :unless => :openid?
な、感じでやればとりあえずよくなる。
とりあえずね。とりあえず。
あとpassword_required?もちょっとだけ手を入れる
def password_required?
if openid? then
crypted_password.blank? || !password.blank?
else
openid?
end
end
すんません。頑張ります><
これで一応両対応
http://localhost:3000/login/signup
から普通にサインアップ
usersに書かれる。
openid_controllerでのログイン処理
def complete #中略 when OpenID::Consumer::SUCCESS #中略 #OpenID::Consumer::SUCCESSの最後で #サイト側の認証 @user = User.get(oidresp.identity_url) if @user.blank? then @user = User.new(:openid_url => oidresp.identity_url) @user.save end self.current_user = @user redirect_to :action => 'mypage/top', :action => "index"
■[VMware]VMwareのCentOSのsendmailから外にメールだす
1. /etc/mail/sendmail.mc 中、「DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')」をコメントアウト。
の部分だけまねしたら出て行った。
■[rails]acts_as_authenticatedとrole_requirementでロール付きの認証。
消えちゃったよ。。
はてなダイアリー素人なので書いたのをなんか間違って消してしまった。。orz
なので、書き直した前半は適当。
acts_as_authenticatedをインストール
$ ruby script/plugin discover $ ruby script/plugin install acts_as_authenticated
ジェネってmigration
$ ./script/generate authenticated user account $ rake db:migrate
その他の機能はあとで
メール認証だの、アクティベーションだのはまた今度。
ログインが必要なコントローラは
before_filter :login_requiredで認証箇所のコントロール
class HogeController < ApplicationController include AuthenticatedSystem before_filter :login_required, :except => [:nologin] def index #ログイン必要 end def nologin #ログイン不要 end end
ロールを追加。
どうせ必要なので。
Acts_as_authenticatedにRole機能を追加する,RoleRequirementっーのがあるみたい。
インストールしる。
$ script/plugin install http://rolerequirement.googlecode.com/svn/tags/role _requirement/ + ./ChangeLog + ./MIT-LICENSE + ./README + ./generators/role/role_generator.rb + ./generators/role/templates/001_add_role_to_users_migration.rb.erb + ./generators/role/templates/_user_functions.erb + ./generators/role_generator_helpers.rb + ./generators/roles/roles_generator.rb + ./generators/roles/templates/001_roles_migration.rb.erb + ./generators/roles/templates/_user_functions.erb + ./generators/roles/templates/role_model.rb.erb + ./generators/roles/templates/roles.yml + ./generators/roles/templates/roles_users.yml + ./generators/roles/templates/users_admin_fixture_with_roles.yml + ./generators/shared_templates/hijacker.rb + ./generators/shared_templates/role_requirement_system.rb.erb + ./generators/shared_templates/role_requirement_test_helper.rb.erb + ./init.rb + ./test/authenticated_system.rb + ./test/controller_stub.rb + ./test/functional/test_role_controller.rb + ./test/test_helper.rb + ./test/user_stub.rb
generate
Role:ロールのモデル名 User:ユーザのモデル名
(ユーザがいくつもロールを持つ:多対多)
script/generate roles Role User
(ユーザは一種類のロールしか持たない:一対多)
script/generate role User
多対多で作っとく。
$ script/generate roles Role User
Generating Role against User
Added the following to the top of app/models/user.rb:
# ---------------------------------------
# The following code has been generated by role_requirement.
# You may wish to modify it to suit your need
has_and_belongs_to_many :roles
attr_protected :roles
# has_role? simply needs to return true or false whether a user has a role or not.
# It may be a good idea to have "admin" roles return true always
def has_role?(role_in_question)
@_list ||= self.roles.collect(&:name)
return true if @_list.include?("admin")
(@_list.include?(role_in_question.to_s) )
end
# ---------------------------------------
Added ApplicationController include to /home/xxxx/dev/rails/auth_test/app/controllers/application.rb
Added RoleRequirement include to /home/xxxx/dev/rails/auth_test/app/controllers/application.rb
Added RoleRequirementTestHelper include to /home/xxxx/dev/rails/auth_test/test/test_helper.rb
create test/fixtures/roles_users.yml
create test/fixtures/roles.yml
create app/models/role.rb
create lib/role_requirement_system.rb
create lib/role_requirement_test_helper.rb
create lib/hijacker.rb
exists db/migrate
create db/migrate/002_create_roles.rb
migrate
DB反映
$ rake db:migrate
(in /home/coek/dev/rails/auth_test)
== 2 CreateRoles: migrating ===================================================
-- create_table("roles")
-> 0.1138s
-- create_table("roles_users", {:id=>false})
-> 0.0181s
-- add_index("roles_users", "role_id")
-> 0.0337s
-- add_index("roles_users", "user_id")
-> 0.0298s
== 2 CreateRoles: migrated (0.1980s) ==========================================
モデルを定義
Roleモデルにhabtmを書き足す
has_and_belongs_to_many :users
ロール設定の画面scaffold
- skip-migrationつけて
$ ruby script/generate scaffold role --skip-migration
exists app/models/
exists app/controllers/
exists app/helpers/
create app/views/roles
exists app/views/layouts/
exists test/functional/
exists test/unit/
create app/views/roles/index.html.erb
create app/views/roles/show.html.erb
create app/views/roles/new.html.erb
create app/views/roles/edit.html.erb
create app/views/layouts/roles.html.erb
create public/stylesheets/scaffold.css
dependency model
exists app/models/
exists test/unit/
exists test/fixtures/
skip app/models/role.rb
create test/unit/role_test.rb
skip test/fixtures/roles.yml
create app/controllers/roles_controller.rb
create test/functional/roles_controller_test.rb
create app/helpers/roles_helper.rb
route map.resources :roles
スキーマ情報とらないからviewをチョコチョコ自分でなおして。。
とりあえず、adminとuserを作っておく。
試してみる
さっき作ったroles_controllerに
require_role "admin"
書いてみて、ログインしないでアクセスすると。ログイン画面に飛ばされる
adminロールを持ってないユーザーでログインしてアクセスすると、画面真っ白。。
画面真っ白がヘボイ
http://d.hatena.ne.jp/clayfish/20080101/1199195090
を参考に
applicationコントローラーに手入れるのめんどかったので
とりあえずリダイレクトだけされすようにした。
/lib/role_requirement_system.rb L110
def access_denied
if logged_in?
#render :nothing => true, :status => 401
redirect_to("/")
return false
else
super
end
end
ロールがある場合も試す。
とりあえずconsoleでロールを与える
$ ruby script/console
Loading development environment (Rails 2.0.2)
>>
?>
?> @user = User.find_by_login('admin')
=> #<User id: 2, login: "admin", email: "xxxx@xxxxx", crypted_password: "xxxxxx", salt: "xxxxxxxx", created_at: "2008-02-12 19:35:08", updated_at: "2008-02-12 19:35:08", remember_token: nil, remember_token_expires_at: nil>
>> @user.roles << Role.find_by_name('admin')
=> [#<Role id: 1, name: "admin">]
>> @user.save
=> true
>>
で、さっきのroles_controllerにアクセスしたら、アクセスできた。
参考
http://blog.japan.zdnet.com/yoshimi/a/2007/10/acts_as_authent.html
http://eringi.com/weblog/archives/2007/07/acts_as_authenticated.html
http://idm.s9.xrea.com/ratio/2007/09/Monthly.html#id_20acts_as_authenticatede381a8e381af