pry-byebug でステップ実行

以前に研修受けた時にも紹介してもらってたpry-byebugの恩恵が受けられたので改めて残しときます。 あと、エラー画面を見やすくするgemも。

better_errors,binding_of_callerはセットでエラー画面をみやすく、pry-byebugはステップ実行に使用します。

# /Gemfile
group :test, :development do
  gem 'better_errors'
  gem 'binding_of_caller'
  gem 'pry-byebug'
end

ブレークポイントを入れたい箇所でソース中に

binding.pry

と入れてやると、処理がそこまで進んだ時にpryターミナルが自動で開きます。
そこで、中身を知りたいオブジェクトを

pry$ p オブジェクト

としてあげると見ることができます。
その時のオブジェクトの状態とか変数の中を取得、編集できるので便利ですね。

Ruby on Rails でOmniAuthで認証してつぶやく

自分の環境だと参考にさせてもらったままだとうまく動かなくて色々いじってみた。 過不足あるかもだけどとりあえず動いたのでまとめ。

https://github.com/sagiO/Ruby_on_Rails_Tweet

できたこと

  • OmniAuthで認証
  • ログインしたユーザでツイート
  • githubにpushしてもコンシューマーキーを隠蔽化(figaroで)

参考

認証:

Ruby on Rails で Oauth を使う - d4i.log

そういうことだったんですね

OmniAuthで認証機能を作る - RuntimeError

ツイート:

Ruby: Rails で Twitter アプリ | snippets.feb19.jp

隠蔽化:

便利gem ~figaro~ - 初心者エンジニアのメモ帳

新規アプリ作成。
gem追加。
OmniAuthはOAuth認証、figaroはキー管理、twittertwitterアクセスに使用。

# /Gemfile
gem 'omniauth-twitter'
gem 'figaro'
gem 'twitter'

bundle install。

$ bundle install

Developers Site にアプリを登録

https://dev.twitter.com

Callback URL を下記で設定

http://127.0.0.1:3000/auth/twitter/callback

「Read and Write」と「Signed in Twitter」にチェック API KEY,API SECRET を控えます。

figaro のインストール

$ rails g figaro install

API KEY,API SECRETを設定

# config/application.yml
TWITTER_KEY: (控えてたAPI KEY)
TWITTER_SECRET:(控えてたAPI SECRET)

OmniAuth 用のイニシャライザーを用意

# config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
    Twitter.configure do |config|
        config.consumer_key = ENV["TWITTER_KEY"]
        config.consumer_secret = ENV["TWITTER_SECRET"]
    end
end

ルートの定義
(ここで、signoutのメソッドがうまくdeleteでは指定できなかった。。なんでだろ??)

# config/routes.rb
  resources :sessions, only: [:create]
  resources :messages, only: [:index, :create]

  root 'sessions#index'

  match '/auth/:provider/callback', to: 'sessions#create', via: 'get'
  match '/signout', to: 'sessions#destroy', via: 'post'

コントローラの作成

$ rails g controller sessions create destroy
$ rails g controller messages create
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

  helper_method :current_user

    def current_user
      @current_user ||= User.find(session[:user_id]) if session[:user_id]
    end
end
# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController

  def create
    auth = request.env["omniauth.auth"]
    user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
    session[:user_id] = user.id
    session[:oauth_token] = auth["credentials"]["token"]
    session[:oauth_token_secret] = auth["credentials"]["secret"]
    redirect_to root_url, notice => "Siged in!"
  end

  def destroy
    session[:user_id] = nil
    session[:oauth_token] = nil
    session[:oauth_token_secret] = nil
    redirect_to root_url, notice => "Signed out!"
  end
end
# app/controllers/messeges_controller.rb
class MessagesController < ApplicationController

  def create
    twitter_client = Twitter::Client.new.configure do |config|
        config.oauth_token = session[:oauth_token]
        config.oauth_token_secret = session[:oauth_token_secret] 
        end
    twitter_client.update(params[:message])
    redirect_to messages_path
  end
end

モデルの作成

$ rails g model user
$ rake db:migrate
# app/models/user.rb
class User < ActiveRecord::Base
  def self.create_with_omniauth(auth)
    create! do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.name = auth["info"]["name"]
    end
  end
end

ビューの作成

# app/views/sessions/index.html
<% if current_user %>
  Welcome <%= current_user.name %>
  <lu>
    <li><%= link_to "ツイート", messages_path %></li> 
      <li><%= link_to "サインアウト", '/signout', method: :destroy %></li> 
     </lu>
<% else %>
  <%= link_to "サインイン with Twitter", "/auth/twitter" %> 
<% end %>
# app/views/messages/index.html
<%= form_tag({action: 'create'}, {method: 'post'}) do %>
    <%= text_field_tag(:message) %>
    <%= submit_tag(:submit) %>
<% end %>

1時間で作るっていうのを見て食いついちゃったんだけど、ズブの素人にはかなり時間かかった。 でも、デバッガとか入れて調査を進める過程を体験できたのでok。 その辺も次で書いとこ。

参考にさせていただいた皆さまに感謝です。

本番環境(production)でbootstrapが反映されない

以前、

heroku へデプロイでエラー「The page you were looking for doesn’t exist.」 - stuby

でherokuにデプロイ後、bootstrapが反映してくれなかったけど、勉強途中だったのでそのままにしてました。 当たり前なのですが、その時気づかなかったのでメモ

ローカルでも、本番環境(production)で起動。

$ rails s --environment production

localhost:3000へアクセスしてみれば、herokuへデプロイした時と同様の表示に。。

調べて見らたら、config/environments/production.rb内の設定で、config.serve_static_assetsの値を変更したりしたら表示できるかもって感じなんだけど改善されず。 参考記事にあるように

この値は静的ファイルをRails自身がサーブするか、NginxやApacheなどのアプリケーションがサーブするかでtrueとfalseを切り替えます。静的ファイルはNginxやApacheが供給すべきなのでプロダクションモードのテストの時など以外にはtrueにしないでね。

bootstrap自体をダウンロードしてきて、asettsの配下に置いたりしたら改善しそうな気もしてきたけど 勉強途中の環境を壊したくないのと、調査に時間を取られるのが嫌なのでタスクに積んどく。

参考:

Rails3 css、js 404 Not Found! 静的ファイルが読み込まれない! - bismar's blog

unicorn - Railsはassetsに注意しろ - Qiita

ActiveRecordという便利なやつ

ActiveRecordSQLを記述するより直感的にキーを指定してDBからデータを取ってこれるっぽいけど 何も考えずに使ってると迷子になりそうなので復習用にリンクを残しとく。

第2回 Active Recordの使い方 | Think IT

  • find 主キーを指定してレコードを取得。先頭レコードを取得するfirst、最終レコードを取得するlast、すべてのレコードを取得するallもあります。

  • where WHERE句を設定します。

  • select 特定の列だけ取得します。selectで列を指定していない場合は、*が使用されます。

  • group GROUP BY句を設定します。

  • order ORDER BY句を設定します。

  • limit LIMIT句を設定します。

  • offset OFFSET句を設定します。

  • joins JOIN句を設定します。

  • includes 関連するテーブルから必要なレコードをまとめて読むeager loadを行います。

  • lock 悲観的ロックを行います。

  • readonly 読み込み専用でレコードを取得します。

  • from データベースビューなどマップされたテーブル以外から読み込む際に使用します。

herokuデプロイしたらbootstrapが反映されない…

Ruby on Rails チュートリアル:実例を使って Rails を学ぼう

の5章までローカル環境で実装してherokuにデプロイしてみたらbootstrapの装飾が反映されませんでした。。 ローカル環境ではちゃんとbootstrapの装飾が反映された形で表示されるのになんでだろう?

heroku へデプロイでエラー「The page you were looking for doesn’t exist.」

Ruby on Rails チュートリアル:実例を使って Rails を学ぼう

で勉強を始めたけど、herokuへデプロイして確認してみた。

$ heroku open

「The page you were looking for doesn’t exist.」(あなたが探していたページは存在しません。) と表示されてしまう。

原因は、単純にheroku openだと一番トップの画面が表示されるがindexページの代わりになるページを用意してなかったから。 勉強用に作成したページのパスをURLに追加して再表示させてやれば表示できた。

上記に気づく前に、assetsをプリコンパイルしてなかったのが原因かもという記事もあったので実はこっちも原因かも。

$ rake assets:precompile

参考: herokuで「The page you were looking for doesn’t exist.」エラーが出るときの対処法 - Qiita [キータ]

おまけ

今回、調べる途中でassetsについてわかりやすくまとめられたページを見つけたし、この先ちょこちょこ詰まる気がするのでメモ。

5分でわかる!? アセットパイプライン(Assets Pipeline) - Rails つまみぐい