2011-04-23

rails3でrinariからmysqlにつなぐメモ


rails3でmysqlを使おうとすると、gem mysql2 を要求された。
なので、config/database.ymlには以下みたいになるが、rinari-sql は "sql-<adapter名>" という名前の関数を探しにいくので、emacs側でsql-mysql2がないというエラーになる。


development:
  adapter: mysql2
  database: foo
  host: localhost
  port: 3306
  username: bar
  password: baz
  encoding: utf8
  pool: 5
  timeout: 5000

これを避けるには、以下のようにしてsql-mysql2にaliasをはるelispをかけばOK


(defalias 'sql-mysql2 'sql-mysql)

2011-04-08

haskellのリスト内包表記で格子点列挙

haskellのリスト内包表記について勉強してるときにたまたまこの記事を見つけたので試しにやってみた。


http://d.hatena.ne.jp/odz/20070131/1170284561


main = mapM print (mesh [[1..10],[1..10],[1..10]])

mesh [] = [[]]
mesh (x:xs) = [ x':xs' | x' <- x, xs' <- (mesh xs) ]

パフォーマンスは調べてません。
もっといいやり方はありそうだけど、そこそこ直感的。。かな?
リスト内包表記って気持ち的にはSQL書くのに近い気がする。

2011-03-27

ruby環境構築メモ - fastri編

いまさらだけど、そろそろまじめにrubyの開発環境を整えようと思ったのでとりあえずfastriを導入した。
5分でおわると思いきや地味に苦労したので作業履歴メモ






手順


  1. 最新版のソースをおとす
  2. 展開してsetup.rbを実行
  3. 'fastri-server -b' でインデックス作成
  4. 'fastri-server -B' でフルテキストのインデックス作成
  5. 'fastri-server' で起動
  6. qri Array みたいなかんじで使う

ところがqriを使おうとすると以下のようなエラーが。。


/usr/lib/ruby/1.8/rdoc/ri/ri_paths.rb:61: uninitialized constant Gem::Version (NameError)
from /usr/lib/ruby/1.8/rdoc/ri/ri_paths.rb:57:in `each'
from /usr/lib/ruby/1.8/rdoc/ri/ri_paths.rb:57
from /usr/local/lib/site_ruby/1.8/fastri/util.rb:38:in `require'
from /usr/local/lib/site_ruby/1.8/fastri/util.rb:38
from /usr/bin/qri:6:in `require'
from /usr/bin/qri:6

色々試した結果、以下のようにfastri/util.rbを書き換えたらとりあえず動くようになった。


--- /home/takayuki/tmp/util.rb  2011-03-27 01:25:51.000000000 +0900
+++ /usr/local/lib/site_ruby/1.8/fastri/util.rb 2011-03-27 01:22:55.000000000 +0900
@@ -35,7 +35,7 @@
# don't let rdoc/ri/ri_paths load rubygems.rb, that takes ~100ms !
emulation = $".all?{|x| /rubygems\.rb$/ !~ x} # 1.9 compatibility
$".unshift "rubygems.rb" if emulation
-require 'rdoc/ri/ri_paths'
+#require 'rdoc/ri/ri_paths'
$".delete "rubygems.rb" if emulation
require 'rdoc/ri/ri_writer'

ちなみに環境は以下の通りです. OSはdebian Lenny


% gem --version
1.6.2
% ruby --version
ruby 1.8.7 (2008-08-11 patchlevel 72) [x86_64-linux]




TODO


  • rvmを導入する

2011-03-22

twitterやfacebookのOAuthをつかってrails+omniauthでログイン機能を実装するメモ その2

前回(http://taksatou.blogspot.com/2011/03/twitterfacebookrails.html) 、OAuthで認証するところまでできたので、今回はtwitterアカウントでログインするところを作ります。

omniauthのrailsチュートリアルビデオのpart2に大体対応してますが、ここでの内容はちょっと変えてます。
- http://railscasts.com/episodes/236-omniauth-part-2


rails generate

以下のようにしてdeviseのセットアップとmigrationをします。
emailとpasswordはつかわないので消します。

rails g devise:install
rails g devise user
rails g migration AddOauthTokenAndOauthTokenSecretToAuthentications oauth_token:string oauth_token_secret:string
rails g migration RemoveEmailAndEncryptedPasswordAndPasswordSaltFromUsers email:string encrypted_password:string password_salt:string

rake db:migrate

model

authenrication.rb

class Authentication < ActiveRecord::Base
  belongs_to :user
end
  • attr_accessibleは必要ないので消します

user.rb

class User < ActiveRecord::Base
  has_many :authentications

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable

  def password_required?
    false
  end
end
  • 今回の場合、userは一つのtwitter認証情報をもつだけなのでhas_manyはおかしいと思うかもしれないですが、今後facebookとかとも連動させたくなったときのためにこうしてます。
  • devise の :validatable パラメータは削除してます。

controller

前回編集したAuthenticationsControllerをさらに以下のように編集します。

class AuthenticationsController < ApplicationController

def create
  omniauth = request.env['omniauth.auth']
  authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])

  if authentication
    sign_in_and_redirect(:user, authentication.user)
  elsif current_user          # 既にログインしてるけど、facebookとかの権限も追加するとき
    current_user.authentications.create!(:provider => omniauth['provider'], :uid => omniauth['uid'],
                                         :oauth_token => omniauth['credentials']['token'],
                                         :oauth_token_secret => omniauth['credentials']['secret'])
    redirect_to authentications_url
  else                        # 新規ユーザのとき
    user = User.new
    user.authentications.build(:provider => omniauth['provider'], :uid => omniauth['uid'],
                               :oauth_token => omniauth['credentials']['token'],
                               :oauth_token_secret => omniauth['credentials']['secret'])
    user.save!
    sign_in_and_redirect(:user, user)
  end
end

view

確認用にauthenticateのviewを以下のように編集します

<h1>Authentications</h1>

<% if user_signed_in? %>
  Signed in as <%= current_user.id %>
  Not you ? <%= link_to "Sign out", destroy_user_session_path %>
<% else %>
  <%= link_to "Sign in", "/auth/twitter" %>
<% end %>


<table>
  <tr>
    <th>User</th>
    <th>Provider</th>
    <th>Uid</th>
  </tr>
  <% if @authentications %>
    <% for authentication in @authentications %>
      <tr>
        <td><%= authentication.user_id %></td>
        <td><%= authentication.provider %></td>
        <td><%= authentication.uid %></td>
        <td><%= link_to "Destroy", authentication, :confirm => 'Are you sure?', :method => :delete %></td>
      </tr>
    <% end %>
  <% end %>
</table>

routes.rb

前回設定した内容にdevise用の設定も追加します

devise_for :users
resources :authentications
match '/auth/:provider/callback' => 'authentications#create'
root :to => "authentications#index"

確認

以上でセットアップはおわりです。
実際に http://localhost:3000/authentications にアクセスしてsign in をクリックしてうまくログインできれば成功です。

以下のようにすればコンソールでtwitterにポストの確認ができるはずです。

$ rails c
Twitter.configure do |config|
  config.consumer_key = 'CONSUMER_KEY'
  config.consumer_secret = 'CONSUMER_SECRET'
  config.oauth_token = User.all[0].authentications[0].oauth_token
  config.oauth_token_secret = User.all[0].authentications[0].oauth_token_secret
end
Twitter.update 'hello, omniauth!'

まとめ

  • 結構大変でした
  • deviseとかomniauthとかそもそもrailsのことをよくわかってないので間違ってたら教えてください

ZenBackWidget