Rails3.2.8 + Pusher

### 参考ページ

[Adding in-app notifications with Pusher | Heroku Dev Center](https://devcenter.heroku.com/articles/pusher_tutorial)

[pusher/notify](https://github.com/pusher/notify)

----

### JSダウンロード

※http／https環境下でFirefox／Chromeの挙動に差異があるため、ローカルに取り込んだ方が無難

http://js.pusher.com/1.11/pusher.min.js
 => app/assets/javascripts/pusher.min.js

### Gemインストール

```ruby:Gemfile
# For Pusher
gem 'pusher'
```

```:ターミナル
bundle install --without production
----------
Installing pusher (0.9.3) 
----------
```

### Herokuアドオンインストール

```:ターミナル
heroku addons:add pusher:sandbox
```

### development用キー取得

※Heroku-Pusherアドオンインストール後ページから
[ development ] => [ API access ] => [ API Credentials how to use these ]

```
Pusher.app_id = 'xxxxx'
Pusher.key    = 'xxxxxxxxxxxxxxxxxxxx'
Pusher.secret = 'xxxxxxxxxxxxxxxxxxxx'
```

↓それぞれの値を設定

```ruby:config/environments/development.rb
  # For Pusher
  require 'pusher'
  
  Pusher.app_id = 'xxxxx'
  Pusher.key    = 'xxxxxxxxxxxxxxxxxxxx'
  Pusher.secret = 'xxxxxxxxxxxxxxxxxxxx'
```

※Heroku上は自動的に設定されるため設定不要

### レシーブ側

```erb:app/views/messages/index.html.erb
<script type="text/javascript">
  var pusher = new Pusher('<%= Pusher.key %>'); // uses your API KEY
  var channel = pusher.subscribe('channel_room_<%= @room.id %>');

  channel.bind( 'message_event_room_<%= @room.id %>', function(data){
    $.get(
      // 送信先
      "/rooms/<%= @room.id %>/messages/list",
      // 送信データ
      null,
      // コールバック
      function(data, status) {
        $('#messages_target_room_<%= @room.id %>').html(data);
      },
      // 応答データ形式
      "html"
    );
  } );
</script>

<%# メッセージリスト %>
<div id="messages_target_room_<%= @room.id %>">
  <%= render partial: 'messages', locals: { room: @room, messages: @messages } %>
</div>
```

```ruby:app/controllers/messages_controller.rb
  #------#
  # list #
  #------#
  def list( room_id )
    room     = Room.where( id: room_id ).first
    messages = Message.where( room_id: room_id ).all

    render partial: 'messages', locals: { room: room, messages: messages }
  end
```

```erb:app/views/messages/_messages.html.erb
<table>
  <tr>
    <th>User</th>
    <th>Sentence</th>
    <th>Created at</th>
    <th></th>
  </tr>

<% messages.each{ |message| %>
  <tr>
    <td><%= render partial: '/layouts/user_icon', locals: { user: message.user } %></td>
    <td><%= raw show_markdown( message.sentence ) if message.sentence.present? %></td>
    <td><%= message.created_at.strftime("%Y/%m/%d %H:%M:%S") %></td>
    <td><% if message.user_id == current_user.id %><%= link_to t( "menu.destroy" ), room_message_path( room, message ), method: :delete, data: { confirm: '本当に削除してよろしいですか？' } %><% end %></td>
  </tr>
<% } %>
</table>
```

### プッシュ側

```ruby:app/controllers/messages_controller.rb
  #--------#
  # create #
  #--------#
  def create( room_id, message )
    @message = Message.new( message )
    @message.user_id = session[:user_id]
    @message.room_id = room_id

    if @message.save
      # Pusherトリガー
      Pusher["channel_room_#{room_id}"].trigger( "message_event_room_#{room_id}", { room_id: room_id } )
      redirect_to( room_messages_path( room_id ) )
    else
      @room = Room.where( id: room_id ).first
      @messages = Message.where( room_id: room_id ).all
      flash[:alert] = "メッセージの投稿に失敗しました。"
      render action: "index"
    end
  end
```

### ローカルサーバ起動

```:ターミナル
rails s
```