ruby-on-rails-4.1partial-page-refreshprivate-pub

Private_pub gem and Rails 4.1.1. The page doesn't get updated after sending a message


For some reason, the page doesn't get updated after sending a message. It works only after refreshing the page manually. I have partially followed this tutorial http://railscasts.com/episodes/316-private-pub but something is not right. Here are my files:

app/controllers/main_controller.rb

class MainController < ApplicationController
  def application
    @messages = Message.all
  end
end

app/controllers/messages_controller.rb

class MessagesController < ApplicationController
    def create
        @message = Message.create(message_params)
    end

    private

        def message_params
            params.require(:message).permit(:content)
        end
end

app/views/layouts/application.html.erb

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <%= viewport_meta_tag %>
    <title><%= content_for?(:title) ? yield(:title) : "Theater" %></title>
    <%= csrf_meta_tags %>

    <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
    <!--[if lt IE 9]>
      <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.6.1/html5shiv.js" type="text/javascript"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.3.0/respond.js" type="text/javascript"></script>
    <![endif]-->

    <%= stylesheet_link_tag "application", :media => "all" %>

    <!-- For third-generation iPad with high-resolution Retina display: -->
    <!-- Size should be 144 x 144 pixels -->
    <%= favicon_link_tag 'apple-touch-icon-144x144-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '144x144' %>

    <!-- For iPhone with high-resolution Retina display: -->
    <!-- Size should be 114 x 114 pixels -->
    <%= favicon_link_tag 'apple-touch-icon-114x114-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '114x114' %>

    <!-- For first- and second-generation iPad: -->
    <!-- Size should be 72 x 72 pixels -->
    <%= favicon_link_tag 'apple-touch-icon-72x72-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '72x72' %>

    <!-- For non-Retina iPhone, iPod Touch, and Android 2.1+ devices: -->
    <!-- Size should be 57 x 57 pixels -->
    <%= favicon_link_tag 'apple-touch-icon-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png' %>

    <!-- For all other devices -->
    <!-- Size should be 32 x 32 pixels -->
    <%= favicon_link_tag 'favicon.ico', :rel => 'shortcut icon' %>
    <%= javascript_include_tag "application" %>
  </head>
  <body data-no-turbolink="true">
    <div id="wrap">

      <%= bootstrap_flash %>
      <%= yield %>

      <div id="push"></div>
    </div>

    <div id="footer">
      <div class="container" align="center">
        <p id="footer-content">Footer</p>
      </div>
    </div>
  </body>
</html>

app/views/main/application.html.erb

<div class="container-fluid">
    <div class="row">
        <div class="col-md-4">Chat column
            <ul id="chat">
                <%= render @messages %>
            </ul>

            <%= form_for Message.new, remote: true do |f| %>
                <%= f.text_field :content %>
                <%= f.submit "Send" %>
            <% end %>
            <%= subscribe_to "messages/new" %>
        </div>
    </div>
</div>

app/views/messages/create.js.erb

<% publish_to "messages/new" do %>
    $("#chat").append("<%= j render(@message) %>");
    $("#chat").animate({
        scrollTop: $("#chat").height()},
        "fast");
<% end %>
$("#new_message")[0].reset();

app/views/messages/_message.html.erb

<li>
    <span class="created_at"><%= message.created_at.strftime("%H:%M") %></span>
    <%= message.content %>
</li>

config/routes.ru

Rails.application.routes.draw do

    resources :messages

    get 'main/application'
    root 'welcome#index'
end

app/models/message.rb

class Message < ActiveRecord::Base
end

Gemfile

source 'https://rubygems.org'

gem 'thin'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.1.1'
# Use postgresql as the database for Active Record
gem 'pg'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.3'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer',  platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0',          group: :doc

# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring',        group: :development

gem 'private_pub'
gem 'rails_12factor', group: :production

gem 'bootstrap-sass', '~> 3.2.0'
gem 'autoprefixer-rails'
gem 'bootstrap-sass-extras'

app/assets/javascripts/application.js

//= require jquery
//= require bootstrap-sprockets
//= require private_pub
//= require jquery_ujs
//= require turbolinks
//= require_tree .

I have also ran

rails g private_pub:install
rackup private_pub.ru -s thin -E production

as private_pub requires it.

Here is a piece of server log that represents the POST after clicking the 'Send' button:

Started POST "/messages" for 127.0.0.1 at 2014-08-01 19:36:44 +0300
Processing by MessagesController#create as JS
  Parameters: {"utf8"=>"✓", "message"=>{"content"=>"Testing"}, "commit"=>"Send"}
   (0.4ms)  BEGIN
  SQL (1.1ms)  INSERT INTO "messages" ("content", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["content", "Testing"], ["created_at", "2014-08-01 16:36:44.301042"], ["updated_at", "2014-08-01 16:36:44.301042"]]
   (1.0ms)  COMMIT
  Rendered messages/_message.html.erb (0.6ms)
  Rendered messages/create.js.erb (7.6ms)
Completed 200 OK in 21ms (Views: 11.7ms | ActiveRecord: 2.9ms)

I hope I have provided information enough. If not, please request more. Thank you in advance.


Solution

  • I think you're just missing this in your messages controller:

    respond_to do |format|

    format.js #calls create.js.erb

    end