Home > Tags > Rails

Rails

rails3でprimary keyとforeign keyをbig intにする

以下は、PostgreSQLの例。

ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = 'bigserial primary key' 


外部キーの場合、t.references :userとか書いてると、ActiveRecord側でintegerがハードコーディングされているのでlimitオプションを付けるしかなさそう。

t.references :user, :limit => 8

RailsDevCon2010で話してきました

RailsDevCon2010、お疲れ様でした。主催かつ発表のお声をくれた@ysakakiさん、スタッフの方々、スピーカー、発表を聞いてくれたみなさま、どうもありがとうございました。

今回、「Railsプロジェクトを成功させるために現場ができること」というタイトルで話したけどびっくりするぐらいRailsに関係のない話。オマケ程度にちょこっと。以下、資料です。

テーマとしては、@ysakakiさんから声をかけて頂いた時に、[Railsの現場でまだまだバージョン管理すらしてないところあるよね。そういう基本的なところを改めて赤松さんの方から話して欲しい」と言うことだったので、個人的に基本的な所と言うと「TDD」と「バージョン管理」(できれば継続インテグレーションもいれたい)だったので、その変も踏まえて技術的負債というトピックを扱った。

具体的な話をしても、スクリーン上じゃコード読みづらいし、わかりにくいかなと思ったので少しぼかした形で発表したわけだけど、全体的にふわふわと掴みどころのない話になってしまったかもしれない。次どこかで発表する時、もしくはブログにでももっと具体的なコードレベルのことを書きたいな。

懇親会は二次会まで参加した。久しぶりに同世代の人と話せたのは楽しかった。ぜひぜひこれからも頑張ってほしい。

scopeでお手軽検索

Rails3.0のscope(2系で言うnamed_scope)を使ったお手軽検索。モデルにextendして使う。やってることは渡されたパラメータのkeyのscopeを呼び出して、それらを全部チェインさせるだけ。お手軽だけど、scopeを定義するだけなので結構融通が効くし便利。

steakのspec/acceptanceをrake statsに反映させる

どうやらsteakで対応してるみたいです(コメント欄参照)。steakのgroupに:developmentを追加すればrake statsの結果にAcceptance specsと表示されます。

結論から言うとrakeファイルを追加して以下のように書けばOK。(Rails.root/lib/tasks/statistics.rakeとかね)

task名がstatsetupなのはrspec-rails/lib/rspec/tasks/rspec.rakeでそうなっている為。cucumberでも同じ要領で大丈夫なはず。rake statsを実行するとちゃんと計算されている。

パスワード変更の機能をどこにもたせるべきか

ちょっと色々わからなくなったので、誰かのアドバイスを期待してここに書く。

簡単に前提を書くと、UserモデルのCRUDとは別にUserのパスワードを変更する画面が必要になった。Usersコントローラにpassword_editみたいなactionを書くのもあまりきれいじゃないなと思ってコントローラを分けることにした。

resources :users do
  resource :password
end

確実にUserのレコードは必要になるので上記の用にネストさせることにした。ここで気になるのがpasswordのコントローラ名。通常PasswordsControllerになる。ただ、PasswordsController内の処理は確実にUserに依存する処理が入るため、これはこれであまりしっくりこない。別にPasswordsControllerを他で使う予定があるわけじゃないけど、User::PasswordsControllerの方がいい気がする。

resources :users do
  resource :password, :only => :edit, :module => 'user'
end
# app/controllers/user/passwords_controller.rb
module User
  PasswordController < ApplicationController::Base

ただ、たかがあるモデルのカラムの為にここまでする必要があるのか?そもそもリソースじゃないよなと思ったりもするわけで。やっぱりUsersコントローラにactionを用意する程度に留めるべきなのだろうか。

追記:10/09/11

やっぱりコントローラを作る(というよりresourcesを追加するのが)がおかしいと思いはじめ、結局気にしてるのはURLなので以下のようにしてみようかなと思う。

resources :user do
  match 'password/edit' => 'users#password_edit'
end

RSpec2+Rails3+autotest環境の構築

9月からやる仕事がめでたく、Rails3.0 + Ruby1.9.2のお仕事なので色々と環境構築。とりあえず自動テストまわりやりました。

一応、環境を他と切り分けるために、rvmでアプリ用にgemsetを用意。アプリごとに簡単に環境を構築できるrvmマジ便利。

gem install bundler --pre
gem install rails

まずは、bundlerとrailsをインストール。次は適当なアプリを作って必要なgemのインストールなどを行う。テストはRSpecで書くので、-TをつけてTest/Unitは使わないようにする。

rails new demo -T

次に必要なgemをGemfileに記述。rspecとかを「テストだけだから」と思って、gropu :testにしたら、モデルを作成したときにTest/Unitのテストコードが作られたりしたので注意。githubのWikiを見るとautotestのgemは不要そうなんだけど、実際ないとうまくautotestが動かなかた。

bundle install

あとはモデルを作って、テストが実行できればOK。

rails g rspec:install
rails g model user
rake
autotest

追記

Twitterで@conceal_rsさんから補足ありました。ありがとうございます!

@ukstudio ZenTestとautotest-railsはなくても大丈夫ですよ。あとrspecは2.0.0.beta.20からwebratに依存しなくなったのでhave_selectorとか使えなくなってます。gem ‘webrat’もあった方がいいかもless than a minute ago via Termtter

warden+railsでパスワード認証

今作っているサービスが後々、OAuth、OpenIDあたりにも対応することになるかもしれないので、そのあたり柔軟に対応できそうなwardenを試してみました。

必要なgemはwardenrails_wardenの2つ。

Userモデルは以下のような感じで。

次にgithubのページを参考にconfig/initializers/warden.rbを追加します。今回はパスワードで認証をしたいのでpasswordのstrategyを自分で追加します。(と言ってもほとんどサンプルと同じ)

この後はUser.authenticateの中身をfind_by_login_and_passwordとかで実装してもいいのですが、それだとパスワードが平文になってしまうのでrestful_authenticationのコードを少し拝借することにします。


includeいているものがrestful_authenticationのコードです。適当にコピーしてlibにでも置いておくといいと思います。

これでpasswordとpassword_confirmationによるパスワードの確認、User#save時にパスワードをハッシュ化して保存してくれます。

後、一応ログイン処理するコントローラも載せておきます。

unauthenticatedが認証に失敗したときに遷移するアクションです。

正直、パスワード認証のことだけ考えるとちょっと面倒な気もします。パスワードの暗号化も自分で書かなければいけないし。ただ、上記のようにmoduleを別途用意しておけば作業の手間自体は結構軽減されので、そこまでは問題にならないかもしれません。

Strategyまわりについてはほとんど検証していませんが、色々と融通は効きそうな気もします。この辺は追々。

後はdeviseというwardenベースのライブラリもあるのでこれを試すのもありかなという気はします。ただ、deviseは色々とやり過ぎというか、多機能すぎてよくわからない感じもしますが・・・

CentOS 5.4(EC2)にApache+PassengerでRails環境作る

後々、また参照する気がするので記録しておく。この手の環境構築系のドキュメントってWikiかなんかにみんなで情報集めたらそこそこ便利そうな気がするのだけどどうだろう。

Ruby、RubyGemsのインストール

yumでRubyをインストールしようとすると、1.8.5が入ってしまうので仕方なくソースからインストール。

$ cd /usr/local/src
$ sudo wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p249.tar.gz
$ sudo tar zxvf ruby-1.8.7-p249.tar.gz
$ cd ruby-1.8.7-p249
$ sudo ./configure
$ sudo make
$ sudo make install

$ cd /usr/local/src
$ sudo wget http://rubyforge.org/frs/download.php/69365/rubygems-1.3.6.tgz
$ sudo tar zxvf rubygems-1.3.6
$ cd rubygems-1.3.6
$ sudo ruby setup.rb

この時点で一応RubyGemsもインストール出来てはいるけれど、実際に使おうとするとエラーが発生する。どうやらzlibが入っていなかった模様。

$ sudo yum install zlib-devel
$ cd /usr/local/src/ruby-1.8.7-p249/ext/zlib
$ sudo extconf.rb --with-zlib-include=/usr/include --with-zlib-lib=/usr/lib
$ sudo make
$ sudo make install

MySQLのインストール

こっちはyumからサクッとインストール。

$ sudo yum install mysql mysql-server mysql-devel
$ sudo /etc/initd.mysqld start

my.cnfの設定は/usr/share/mysql/以下からコピーしてきたりとか適当に。ユーザの設定とかも適当に。

Apache+Passenger

まずはApacheをサクッとインストール。

$ sudo yum install httpd-devel

そしてPassengerのインストール。

$ sudo gem install passenger
$ sudo passenger-install-apache2-module

ここでまたしてもエラー。どうやらOpenSSLが入っていないとかなんとか。

$ sudo yum install openssl-devel
$ cd /usr/local/src/ruby-1.8.7-p249/ext/openssl
$ sudo ruby extconf.rb
$ sudo make
$ sudo make install

これで無事Passengerがインストール出来る。

$ sudo passenger-install-apache2-module

最低限のPassengerの設定。この設定の内容はpassenger-install-apache2-moduleを実行した時に表示されているので確認しておくこと。

$ sudo vi /etc/httpd/conf.d/passenger.conf
LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.11/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.11
PassengerRuby /usr/local/bin/ruby

あとはhttpd.confのDocumentRootをRailsのpublicディレクトリにすればOK。

$ sudo vi /etc/httpd/conf/httpd.conf
DocumentRoot /path/to/rails/public

本当に最低限だけどとりあえずこれでPassengerでRailsを動かすことが出来るはず。ApacheやMySQLの自動起動はchkconfigを設定すればよい。Passengerの細かい設定はPassenger users guidを参考に。

RailsからOAuthを利用してTwitterにポストする

OAuthの細かい説明は抜き。

まず、OAuthを使うためにはTwitterでアプリケーションの登録が必要なので、http://twitter.com/oauth_clientsで登録をしておいてください。 以下のコードの6行目の部分を取得したConsumer keyとConsumer secretをに置き換えてください。

適当なところからverifyアクションにリダイレクトしてくると、さらにTwitterにリダイレクトします。その後、callbackアクションに戻ってくるので、そこで認証して取得したトークンをUserモデルに保存します。(ここでは自分のサービスにログインしているユーザが認証を行っています。)

その後、保存したトークンを使ってTwitterに発言をします。リクエストが受け入れられなかった場合の処理などは省いてます。

Twitterには取得したトークンに有効期限はありませんが、有効期限が存在するものもある(どちらかというとそっちの方が多いのかも)気をつける必要があります。

ちなみに細かいことを調べていないので「トークンをDBに保存してしまっていいのか」とか「トークンが外部に漏れてしまった場合はどうしたらいいのか」などについてはよくわかっていません。

WEB+DB PRESS Vol.51でRailsの特集を執筆しました

WEB+DB PRESS Vol.51
WEB+DB PRESS Vol.51 WEB+DB PRESS編集部

技術評論社 2009-06-24
売り上げランキング : 130

Amazonで詳しく見る by G-Tools

僕個人っていうわけではないですが、会社の人達と一緒に6月24日発売のWEB+DB PRESS Vol.51で執筆させて頂きました。初めての執筆活動なので、読みにくい部分、至らない部分などあると思いますが、買って読んで頂けると幸いです。

Home > Tags > Rails

Feeds
Meta
Others

Return to page top