├── log └── .keep ├── app ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── concerns │ │ └── .keep │ └── comment.rb ├── assets │ ├── images │ │ ├── .keep │ │ └── gundam.jpg │ ├── javascripts │ │ ├── application.js │ │ ├── components.js │ │ └── react_components │ │ │ ├── _comment.js.jsx │ │ │ ├── _comment_list.js.jsx │ │ │ ├── _comment_box.js.jsx │ │ │ └── _comment_form.js.jsx │ └── stylesheets │ │ ├── _base.sass │ │ └── application.css ├── controllers │ ├── concerns │ │ └── .keep │ ├── application_controller.rb │ └── comments_controller.rb ├── helpers │ └── application_helper.rb └── views │ ├── comments │ └── index.html.erb │ └── layouts │ └── application.html.erb ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── public ├── favicon.ico ├── robots.txt ├── 500.html ├── 422.html └── 404.html ├── test ├── helpers │ ├── .keep │ ├── home_helper_test.rb │ └── comments_helper_test.rb ├── mailers │ └── .keep ├── models │ ├── .keep │ └── comment_test.rb ├── controllers │ ├── .keep │ ├── comments_controller_test.rb │ └── home_controller_test.rb ├── fixtures │ ├── .keep │ └── comments.yml ├── integration │ └── .keep └── test_helper.rb ├── vendor └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep ├── bin ├── rake ├── bundle └── rails ├── config ├── routes.rb ├── boot.rb ├── environment.rb ├── initializers │ ├── session_store.rb │ ├── filter_parameter_logging.rb │ ├── mime_types.rb │ ├── backtrace_silencers.rb │ ├── wrap_parameters.rb │ ├── inflections.rb │ └── secret_token.rb ├── locales │ └── en.yml ├── database.yml ├── application.rb └── environments │ ├── development.rb │ ├── test.rb │ └── production.rb ├── config.ru ├── db ├── migrate │ └── 20140315030553_create_comments.rb ├── seeds.rb └── schema.rb ├── Rakefile ├── .gitignore ├── README.md ├── Gemfile └── Gemfile.lock /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/comment.rb: -------------------------------------------------------------------------------- 1 | class Comment < ActiveRecord::Base 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /test/helpers/home_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HomeHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /app/assets/images/gundam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bensmithett/sample-react-rails-app/HEAD/app/assets/images/gundam.jpg -------------------------------------------------------------------------------- /test/helpers/comments_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CommentsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | SampleReactRailsApp::Application.routes.draw do 2 | resources :comments 3 | root :to => redirect("/comments") 4 | end 5 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | //= require jquery 2 | 3 | //= require react 4 | //= require react_ujs 5 | 6 | //= require_tree ./react_components 7 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /test/models/comment_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CommentTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /app/assets/javascripts/components.js: -------------------------------------------------------------------------------- 1 | // A manifest containing all React components. 2 | // This file is used by react-rails for server-rendering components. 3 | 4 | //= require_tree ./react_components -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | # Set up gems listed in the Gemfile. 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | 4 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 5 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | SampleReactRailsApp::Application.initialize! 6 | -------------------------------------------------------------------------------- /test/controllers/comments_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CommentsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | SampleReactRailsApp::Application.config.session_store :cookie_store, key: '_sample-react-rails-app_session' 4 | -------------------------------------------------------------------------------- /app/views/comments/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= react_component('CommentBox', 2 | {:presenter => @presenter.to_json, :imgSrc => image_path("gundam.jpg")}, 3 | {:prerender => true}) %> 4 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /test/fixtures/comments.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | author: MyString 5 | text: MyText 6 | 7 | two: 8 | author: MyString 9 | text: MyText 10 | -------------------------------------------------------------------------------- /test/controllers/home_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HomeControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index 6 | assert_response :success 7 | end 8 | 9 | end 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_base.sass: -------------------------------------------------------------------------------- 1 | .content 2 | font-family: sans-serif 3 | margin: 0 auto 4 | max-width: 400px 5 | position: relative 6 | 7 | img 8 | max-width: 100% 9 | 10 | textarea 11 | height: 70px 12 | width: 100% 13 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140315030553_create_comments.rb: -------------------------------------------------------------------------------- 1 | class CreateComments < ActiveRecord::Migration 2 | def change 3 | create_table :comments do |t| 4 | t.string :author 5 | t.text :text 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | SampleReactRailsApp::Application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/javascripts/react_components/_comment.js.jsx: -------------------------------------------------------------------------------- 1 | var Comment = React.createClass({ 2 | render: function () { 3 | return ( 4 |
5 |

{ this.props.author } said:

6 |

{ this.props.text }

7 |
8 | ) 9 | } 10 | }); 11 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | -------------------------------------------------------------------------------- /app/assets/javascripts/react_components/_comment_list.js.jsx: -------------------------------------------------------------------------------- 1 | var CommentList = React.createClass({ 2 | render: function () { 3 | var commentNodes = this.props.comments.map(function ( comment ) { 4 | return 5 | }); 6 | 7 | return ( 8 |
9 | { commentNodes } 10 |
11 | ) 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/*.log 16 | /tmp 17 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] ||= "test" 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | ActiveRecord::Migration.check_pending! 7 | 8 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 9 | # 10 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 11 | # -- they do not yet inherit this setting 12 | fixtures :all 13 | 14 | # Add more helper methods to be used by all tests here... 15 | end 16 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require_tree . 13 | */ 14 | -------------------------------------------------------------------------------- /app/controllers/comments_controller.rb: -------------------------------------------------------------------------------- 1 | class CommentsController < ApplicationController 2 | def index 3 | @presenter = { 4 | :comments => Comment.last(5), 5 | :form => { 6 | :action => comments_path, 7 | :csrf_param => request_forgery_protection_token, 8 | :csrf_token => form_authenticity_token 9 | } 10 | } 11 | end 12 | 13 | def create 14 | @comment = Comment.new(comment_params) 15 | @comment.save 16 | 17 | if request.xhr? 18 | render :json => Comment.last(5) 19 | else 20 | redirect_to comments_path 21 | end 22 | end 23 | 24 | private 25 | 26 | def comment_params 27 | params.require(:comment).permit(:author, :text) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure your secret_key_base is kept private 11 | # if you're sharing your code publicly. 12 | SampleReactRailsApp::Application.config.secret_key_base = '51f681017345c45b4a63bdfcc590218f3372bbbba700a6da4ead112d76cc63d15eee1dec086020ccd5e86368c30945450872c4b52b67940696a23227dc7e9225' 13 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sample Rails app with isomorphic React components 2 | 3 | This is a simple proof-of-concept Rails app that uses the 1.x prerelease version of the [react-rails gem](https://github.com/reactjs/react-rails/pull/24), which lets us: 4 | 5 | - render [React](http://facebook.github.io/react/index.html) components server side 6 | - mount the same React component on top of the server-rendered DOM client side (via an unobtrusive JS adapter) 7 | 8 | The app displays a photo with simple list of comments and a form for adding new comments. New comments are added via Ajax, but if JS fails to load (which you can test with `?js=broken`), the form submits via a full page refresh. 9 | 10 | To get the app running: 11 | 12 | - `bundle install` 13 | - `rake db:migrate` 14 | - `rails server` 15 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # development: 7 | # adapter: sqlite3 8 | # database: db/development.sqlite3 9 | # pool: 5 10 | # timeout: 5000 11 | 12 | # Heroku told me to put this stuff here: 13 | development: 14 | adapter: postgresql 15 | encoding: unicode 16 | database: myapp_development 17 | pool: 5 18 | password: 19 | 20 | # Warning: The database defined as "test" will be erased and 21 | # re-generated from your development database when you run "rake". 22 | # Do not set this db to the same as development or production. 23 | test: 24 | adapter: sqlite3 25 | database: db/test.sqlite3 26 | pool: 5 27 | timeout: 5000 28 | 29 | production: 30 | adapter: sqlite3 31 | database: db/production.sqlite3 32 | pool: 5 33 | timeout: 5000 34 | -------------------------------------------------------------------------------- /app/assets/javascripts/react_components/_comment_box.js.jsx: -------------------------------------------------------------------------------- 1 | var CommentBox = React.createClass({ 2 | getInitialState: function () { 3 | return JSON.parse(this.props.presenter); 4 | }, 5 | 6 | handleCommentSubmit: function ( formData, action ) { 7 | $.ajax({ 8 | data: formData, 9 | url: action, 10 | type: "POST", 11 | dataType: "json", 12 | success: function ( data ) { 13 | this.setState({ comments: data }); 14 | }.bind(this) 15 | }); 16 | }, 17 | 18 | render: function () { 19 | return ( 20 |
21 | { 22 | 23 |
24 |

Add a comment:

25 | 26 |
27 | ); 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sample Rails app using react-rails 5 | <%= stylesheet_link_tag "application", media: "all" %> 6 | <%= csrf_meta_tags %> 7 | 8 | 9 |
10 | <%= yield %> 11 |
12 | 13 | <% unless params[:js] == "broken" %> 14 | <%= javascript_include_tag "application" %> 15 | <% end %> 16 | 17 | <% if Rails.env.production? %> 18 | 27 | <% end %> 28 | 29 | 30 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module SampleReactRailsApp 10 | class Application < Rails::Application 11 | # Settings in config/environments/* take precedence over those specified here. 12 | # Application configuration should go into files in config/initializers 13 | # -- all .rb files in that directory are automatically loaded. 14 | 15 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 16 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 17 | # config.time_zone = 'Central Time (US & Canada)' 18 | 19 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 20 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 21 | # config.i18n.default_locale = :de 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 20140315030553) do 15 | 16 | # These are extensions that must be enabled in order to support this database 17 | enable_extension "plpgsql" 18 | 19 | create_table "comments", force: true do |t| 20 | t.string "author" 21 | t.text "text" 22 | t.datetime "created_at" 23 | t.datetime "updated_at" 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | SampleReactRailsApp::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | end 30 | -------------------------------------------------------------------------------- /app/assets/javascripts/react_components/_comment_form.js.jsx: -------------------------------------------------------------------------------- 1 | var CommentForm = React.createClass({ 2 | handleSubmit: function ( event ) { 3 | event.preventDefault(); 4 | 5 | var author = this.refs.author.getDOMNode().value.trim(); 6 | var text = this.refs.text.getDOMNode().value.trim(); 7 | 8 | // validate 9 | if (!text || !author) { 10 | return false; 11 | } 12 | 13 | // submit 14 | var formData = $( this.refs.form.getDOMNode() ).serialize(); 15 | this.props.onCommentSubmit( formData, this.props.form.action ); 16 | 17 | // reset form 18 | this.refs.author.getDOMNode().value = ""; 19 | this.refs.text.getDOMNode().value = ""; 20 | }, 21 | render: function () { 22 | return ( 23 |
24 |

25 |

26 |