4 |
--------------------------------------------------------------------------------
/app/views/api/chirps/show.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.partial! 'api/chirps/chirp', chirp: @chirp
2 |
--------------------------------------------------------------------------------
/wiki/bluebird_user_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appacademy/bluebird/HEAD/wiki/bluebird_user_search.png
--------------------------------------------------------------------------------
/app/controllers/root_controller.rb:
--------------------------------------------------------------------------------
1 | class RootController < ApplicationController
2 | def root
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/wiki/bluebird_session_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appacademy/bluebird/HEAD/wiki/bluebird_session_page.png
--------------------------------------------------------------------------------
/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | class ApplicationRecord < ActiveRecord::Base
2 | self.abstract_class = true
3 | end
4 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 |
--------------------------------------------------------------------------------
/wiki/bluebird_chirp_form_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appacademy/bluebird/HEAD/wiki/bluebird_chirp_form_page.png
--------------------------------------------------------------------------------
/wiki/bluebird_dashboard_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appacademy/bluebird/HEAD/wiki/bluebird_dashboard_page.png
--------------------------------------------------------------------------------
/wiki/bluebird_show_chirp_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appacademy/bluebird/HEAD/wiki/bluebird_show_chirp_page.png
--------------------------------------------------------------------------------
/app/channels/application_cable/channel.rb:
--------------------------------------------------------------------------------
1 | module ApplicationCable
2 | class Channel < ActionCable::Channel::Base
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/app/assets/config/manifest.js:
--------------------------------------------------------------------------------
1 | //= link_tree ../images
2 | //= link_directory ../javascripts .js
3 | //= link_directory ../stylesheets .css
4 |
--------------------------------------------------------------------------------
/app/views/api/chirps/index.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.array! @chirps do |chirp|
2 | json.partial! 'api/chirps/chirp', chirp: chirp
3 | end
4 |
5 |
--------------------------------------------------------------------------------
/app/channels/application_cable/connection.rb:
--------------------------------------------------------------------------------
1 | module ApplicationCable
2 | class Connection < ActionCable::Connection::Base
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/app/mailers/application_mailer.rb:
--------------------------------------------------------------------------------
1 | class ApplicationMailer < ActionMailer::Base
2 | default from: 'from@example.com'
3 | layout 'mailer'
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 |
--------------------------------------------------------------------------------
/config/spring.rb:
--------------------------------------------------------------------------------
1 | %w(
2 | .ruby-version
3 | .rbenv-vars
4 | tmp/restart.txt
5 | tmp/caching-dev.txt
6 | ).each { |path| Spring.watch(path) }
7 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
2 |
3 | require 'bundler/setup' # Set up gems listed in the Gemfile.
4 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require_relative 'config/environment'
4 |
5 | run Rails.application
6 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require_relative 'application'
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/db/migrate/20170816171327_add_index_to_chirp.rb:
--------------------------------------------------------------------------------
1 | class AddIndexToChirp < ActiveRecord::Migration[5.1]
2 | def change
3 | add_index :chirps, :author_id
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170816164052_add_email_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddEmailToUsers < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :users, :email, :string
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/app/views/layouts/_errors.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <% if flash[:errors] %>
3 | <% flash[:errors].each do |error| %>
4 |
<%= error %>
5 | <% end %>
6 | <% end %>
7 |
--------------------------------------------------------------------------------
/frontend/reducers/entities.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 | import chirpsReducer from './chirps';
3 |
4 | export default combineReducers({
5 | chirps: chirpsReducer
6 | });
7 |
--------------------------------------------------------------------------------
/app/views/api/chirps/_chirp.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.extract! chirp, :id, :body, :author_id
2 | json.likes chirp.likes.count
3 | json.liked_by_current_user !!chirp.likes.find_by(user_id: current_user.id)
4 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test/controllers/chirps_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class ChirpsControllerTest < ActionDispatch::IntegrationTest
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/test/controllers/likes_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class LikesControllerTest < ActionDispatch::IntegrationTest
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/test/controllers/users_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class UsersControllerTest < ActionDispatch::IntegrationTest
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/test/application_system_test_case.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
4 | driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
5 | end
6 |
--------------------------------------------------------------------------------
/test/controllers/follows_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class FollowsControllerTest < ActionDispatch::IntegrationTest
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/test/controllers/api/chirps_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class Api::ChirpsControllerTest < ActionDispatch::IntegrationTest
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/test/controllers/api/likes_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class Api::LikesControllerTest < ActionDispatch::IntegrationTest
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/test/controllers/api/users_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class Api::UsersControllerTest < ActionDispatch::IntegrationTest
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/chirps.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the chirps controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/likes.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the likes controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/root.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the root controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/users.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the users controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/config/cable.yml:
--------------------------------------------------------------------------------
1 | development:
2 | adapter: async
3 |
4 | test:
5 | adapter: async
6 |
7 | production:
8 | adapter: redis
9 | url: redis://localhost:6379/1
10 | channel_prefix: BlueBird_production
11 |
--------------------------------------------------------------------------------
/test/controllers/api/sessions_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class Api::SessionsControllerTest < ActionDispatch::IntegrationTest
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/follows.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the Follows controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/sessions.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the sessions controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/api/chirps.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the API::Chirps controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/api/likes.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the API::Likes controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/api/users.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the API::Users controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/api/sessions.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the API::Sessions controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/config/initializers/application_controller_renderer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # ApplicationController.renderer.defaults.merge!(
4 | # http_host: 'example.org',
5 | # https: false
6 | # )
7 |
--------------------------------------------------------------------------------
/frontend/components/nav_bar/welcome_bar.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default ({ user }) => (
4 |
5 |
Bluebird
6 |
Welcome { user.username }!
7 |
8 | );
9 |
--------------------------------------------------------------------------------
/frontend/thunk/thunk.js:
--------------------------------------------------------------------------------
1 | const thunk = ({ dispatch, getState }) => next => action => {
2 | if (typeof action === 'function') {
3 | return action(dispatch, getState);
4 | }
5 | return next(action);
6 | };
7 |
8 | export default thunk;
--------------------------------------------------------------------------------
/app/assets/javascripts/likes.coffee:
--------------------------------------------------------------------------------
1 | # Place all the behaviors and hooks related to the matching controller here.
2 | # All this logic will automatically be available in application.js.
3 | # You can use CoffeeScript in this file: http://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/javascripts/root.coffee:
--------------------------------------------------------------------------------
1 | # Place all the behaviors and hooks related to the matching controller here.
2 | # All this logic will automatically be available in application.js.
3 | # You can use CoffeeScript in this file: http://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/javascripts/users.coffee:
--------------------------------------------------------------------------------
1 | # Place all the behaviors and hooks related to the matching controller here.
2 | # All this logic will automatically be available in application.js.
3 | # You can use CoffeeScript in this file: http://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test/controllers/root_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class RootControllerTest < ActionDispatch::IntegrationTest
4 | test "should get root" do
5 | get root_root_url
6 | assert_response :success
7 | end
8 |
9 | end
10 |
--------------------------------------------------------------------------------
/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_relative 'config/application'
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/app/assets/javascripts/api/chirps.coffee:
--------------------------------------------------------------------------------
1 | # Place all the behaviors and hooks related to the matching controller here.
2 | # All this logic will automatically be available in application.js.
3 | # You can use CoffeeScript in this file: http://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/javascripts/api/likes.coffee:
--------------------------------------------------------------------------------
1 | # Place all the behaviors and hooks related to the matching controller here.
2 | # All this logic will automatically be available in application.js.
3 | # You can use CoffeeScript in this file: http://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/javascripts/api/users.coffee:
--------------------------------------------------------------------------------
1 | # Place all the behaviors and hooks related to the matching controller here.
2 | # All this logic will automatically be available in application.js.
3 | # You can use CoffeeScript in this file: http://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/javascripts/chirps.coffee:
--------------------------------------------------------------------------------
1 | # Place all the behaviors and hooks related to the matching controller here.
2 | # All this logic will automatically be available in application.js.
3 | # You can use CoffeeScript in this file: http://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/javascripts/follows.coffee:
--------------------------------------------------------------------------------
1 | # Place all the behaviors and hooks related to the matching controller here.
2 | # All this logic will automatically be available in application.js.
3 | # You can use CoffeeScript in this file: http://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/javascripts/sessions.coffee:
--------------------------------------------------------------------------------
1 | # Place all the behaviors and hooks related to the matching controller here.
2 | # All this logic will automatically be available in application.js.
3 | # You can use CoffeeScript in this file: http://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/app/assets/javascripts/api/sessions.coffee:
--------------------------------------------------------------------------------
1 | # Place all the behaviors and hooks related to the matching controller here.
2 | # All this logic will automatically be available in application.js.
3 | # You can use CoffeeScript in this file: http://coffeescript.org/
4 |
--------------------------------------------------------------------------------
/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | begin
3 | load File.expand_path('../spring', __FILE__)
4 | rescue LoadError => e
5 | raise unless e.message.include?('spring')
6 | end
7 | require_relative '../config/boot'
8 | require 'rake'
9 | Rake.application.run
10 |
--------------------------------------------------------------------------------
/frontend/reducers/root.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 | import sessionReducer from './session';
3 | import entitiesReducer from './entities';
4 |
5 | export default combineReducers({
6 | entities: entitiesReducer,
7 | session: sessionReducer
8 | });
--------------------------------------------------------------------------------
/db/migrate/20170816162825_create_users.rb:
--------------------------------------------------------------------------------
1 | class CreateUsers < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :users do |t|
4 | t.string :username, null: false
5 | end
6 |
7 | add_index :users, :username, unique: true
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20170823202541_add_stuff_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddStuffToUsers < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :users, :password_digest, :string
4 | add_column :users, :session_token, :string
5 | add_index :users, :session_token
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20170816174156_create_likes.rb:
--------------------------------------------------------------------------------
1 | class CreateLikes < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :likes do |t|
4 | t.integer :user_id, null: false
5 | t.integer :chirp_id, null: false
6 | t.timestamps
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/config/initializers/cookies_serializer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Specify a serializer for the signed and encrypted cookie jars.
4 | # Valid options are :json, :marshal, and :hybrid.
5 | Rails.application.config.action_dispatch.cookies_serializer = :json
6 |
--------------------------------------------------------------------------------
/db/migrate/20170816170838_create_chirps.rb:
--------------------------------------------------------------------------------
1 | class CreateChirps < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :chirps do |t|
4 | t.text :body, null: false
5 | t.integer :author_id, null: false
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | begin
3 | load File.expand_path('../spring', __FILE__)
4 | rescue LoadError => e
5 | raise unless e.message.include?('spring')
6 | end
7 | APP_PATH = File.expand_path('../config/application', __dir__)
8 | require_relative '../config/boot'
9 | require 'rails/commands'
10 |
--------------------------------------------------------------------------------
/frontend/components/nav_bar/welcome_bar_container.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {connect} from 'react-redux';
3 | import WelcomeBar from './welcome_bar';
4 |
5 | const mapStateToProps = (state) => ({
6 | user: state.session.currentUser
7 | });
8 |
9 | export default connect(mapStateToProps)(WelcomeBar);
--------------------------------------------------------------------------------
/app/views/layouts/mailer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
--------------------------------------------------------------------------------
/frontend/components/root.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Provider } from 'react-redux';
3 | import { HashRouter } from 'react-router-dom';
4 | import App from './app';
5 |
6 | export default ({store}) => (
7 |
8 |
9 |
10 |
11 |
12 | );
13 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../../config/environment', __FILE__)
2 | require 'rails/test_help'
3 |
4 | class ActiveSupport::TestCase
5 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
6 | fixtures :all
7 |
8 | # Add more helper methods to be used by all tests here...
9 | end
10 |
--------------------------------------------------------------------------------
/bin/yarn:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | VENDOR_PATH = File.expand_path('..', __dir__)
3 | Dir.chdir(VENDOR_PATH) do
4 | begin
5 | exec "yarnpkg #{ARGV.join(" ")}"
6 | rescue Errno::ENOENT
7 | $stderr.puts "Yarn executable was not detected in the system."
8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
9 | exit 1
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/frontend/components/home/home.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default () => (
4 |
5 |
6 |
7 |
8 |
Where birds can chirp.
9 |
10 | )
11 |
--------------------------------------------------------------------------------
/db/migrate/20170828221731_create_follows.rb:
--------------------------------------------------------------------------------
1 | class CreateFollows < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :follows do |t|
4 | t.integer :follower_id, null: false
5 | t.integer :followee_id, null: false
6 | t.timestamps
7 | end
8 |
9 | add_index :follows, :follower_id
10 | add_index :follows, :followee_id
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/frontend/components/session/signup_container.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'react-redux';
3 | import { createNewUser } from '../../actions/session';
4 | import Signup from './signup';
5 |
6 | const mapDispatchToProps = (dispatch) => ({
7 | createNewUser: formUser => dispatch(createNewUser(formUser)),
8 | });
9 |
10 | export default connect(undefined, mapDispatchToProps)(Signup);
11 |
--------------------------------------------------------------------------------
/frontend/components/session/login_container.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'react-redux';
3 | import { login } from '../../actions/session';
4 | import Login from './login';
5 | import { withRouter } from 'react-router-dom';
6 |
7 | const mapDispatchToProps = (dispatch) => ({
8 | login: formUser => dispatch(login(formUser)),
9 | });
10 |
11 | export default connect(undefined, mapDispatchToProps)(Login);
12 |
--------------------------------------------------------------------------------
/app/assets/javascripts/cable.js:
--------------------------------------------------------------------------------
1 | // Action Cable provides the framework to deal with WebSockets in Rails.
2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command.
3 | //
4 | //= require action_cable
5 | //= require_self
6 | //= require_tree ./channels
7 |
8 | (function() {
9 | this.App || (this.App = {});
10 |
11 | App.cable = ActionCable.createConsumer();
12 |
13 | }).call(this);
14 |
--------------------------------------------------------------------------------
/frontend/store/store.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from 'redux';
2 | import { composeWithDevTools } from 'redux-devtools-extension';
3 | import { createLogger } from 'redux-logger';
4 |
5 | import rootReducer from '../reducers/root';
6 | import thunk from '../thunk/thunk';
7 |
8 | export default (preloadedState = {}) => createStore(
9 | rootReducer, preloadedState,
10 | composeWithDevTools(applyMiddleware(createLogger(), thunk))
11 | );
12 |
--------------------------------------------------------------------------------
/frontend/utils/chirps.js:
--------------------------------------------------------------------------------
1 | export const getChirps = () => {
2 | return $.ajax({
3 | url: '/api/chirps'
4 | });
5 | }
6 |
7 | export const postLikeToChirp = id => {
8 | return $.ajax({
9 | url: '/api/likes',
10 | method: 'POST',
11 | data: { id }
12 | });
13 | }
14 |
15 | export const deleteLikeFromChirp = id => {
16 | return $.ajax({
17 | url: '/api/likes',
18 | method: 'DELETE',
19 | data: { id }
20 | });
21 | }
22 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/frontend/components/nav_bar/nav_bar_container.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {connect} from 'react-redux';
3 | import NavBar from './nav_bar';
4 | import { logout } from '../../actions/session';
5 |
6 | const mapStateToProps = (state) => ({
7 | currentUser: state.session.currentUser
8 | });
9 |
10 | const mapDispatchToProps = (dispatch) => ({
11 | logout: () => dispatch(logout())
12 | })
13 |
14 | export default connect(mapStateToProps, mapDispatchToProps)(NavBar);
--------------------------------------------------------------------------------
/test/models/like_test.rb:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | #
3 | # Table name: likes
4 | #
5 | # id :integer not null, primary key
6 | # user_id :integer not null
7 | # chirp_id :integer not null
8 | # created_at :datetime not null
9 | # updated_at :datetime not null
10 | #
11 |
12 | require 'test_helper'
13 |
14 | class LikeTest < ActiveSupport::TestCase
15 | # test "the truth" do
16 | # assert true
17 | # end
18 | end
19 |
--------------------------------------------------------------------------------
/test/controllers/sessions_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class SessionsControllerTest < ActionDispatch::IntegrationTest
4 | test "should get new" do
5 | get sessions_new_url
6 | assert_response :success
7 | end
8 |
9 | test "should get create" do
10 | get sessions_create_url
11 | assert_response :success
12 | end
13 |
14 | test "should get destroy" do
15 | get sessions_destroy_url
16 | assert_response :success
17 | end
18 |
19 | end
20 |
--------------------------------------------------------------------------------
/test/models/chirp_test.rb:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | #
3 | # Table name: chirps
4 | #
5 | # id :integer not null, primary key
6 | # body :text not null
7 | # author_id :integer not null
8 | # created_at :datetime not null
9 | # updated_at :datetime not null
10 | #
11 |
12 | require 'test_helper'
13 |
14 | class ChirpTest < ActiveSupport::TestCase
15 | # test "the truth" do
16 | # assert true
17 | # end
18 | end
19 |
--------------------------------------------------------------------------------
/test/models/follow_test.rb:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | #
3 | # Table name: follows
4 | #
5 | # id :integer not null, primary key
6 | # follower_id :integer not null
7 | # followee_id :integer not null
8 | # created_at :datetime not null
9 | # updated_at :datetime not null
10 | #
11 |
12 | require 'test_helper'
13 |
14 | class FollowTest < ActiveSupport::TestCase
15 | # test "the truth" do
16 | # assert true
17 | # end
18 | end
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Blue Bird
2 |
3 | ### July 31, 2017 App Academy Cohort
4 |
5 | 
6 |
7 | ##### W3D3
8 |
9 | + Added bare bones migration files for Users, Chirps, and Likes
10 | + Added basic model validations, associations and custom validations for the above tables
11 |
12 | ##### W4D1
13 |
14 | + Added routes and controllers for Users, Chirps, and Likes
15 |
16 | ##### W4D2
17 |
18 | + Added views for Users and Chirps (delaying likes until auth)
19 |
--------------------------------------------------------------------------------
/app/controllers/follows_controller.rb:
--------------------------------------------------------------------------------
1 | class FollowsController < ApplicationController
2 | def create
3 | @follow = Follow.new
4 | @follow.followee_id = params[:id]
5 | @follow.follower_id = current_user.id
6 | unless @follow.save
7 | flash[:errors] = @follow.errors.full_messages
8 | end
9 | redirect_to user_url(params[:id])
10 | end
11 |
12 | def destroy
13 | @follow = Follow.find(params[:id])
14 | @follow.destroy
15 | redirect_to user_url(@follow.followee_id)
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/app/controllers/api/sessions_controller.rb:
--------------------------------------------------------------------------------
1 | class Api::SessionsController < ApplicationController
2 | def create
3 | # Find user by credentials
4 | @user = User.find_by_credentials(params[:user][:username], params[:user][:password])
5 | if @user.nil?
6 | render json: ['Nope. Wrong credentials!'], status: 401
7 | else
8 | login!(@user)
9 | render 'api/users/show';
10 | end
11 | end
12 |
13 | def destroy
14 | logout!
15 | render json: { message: 'Logout successful.' }
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/frontend/reducers/session.js:
--------------------------------------------------------------------------------
1 | import { RECEIVE_CURRENT_USER, LOGOUT_CURRENT_USER } from '../actions/session';
2 |
3 | const _nullSession = {
4 | currentUser: null
5 | };
6 |
7 | export default (state = _nullSession, action) => {
8 | Object.freeze(state);
9 | switch(action.type) {
10 | case RECEIVE_CURRENT_USER:
11 | const currentUser = action.user
12 | return Object.assign({}, { currentUser });
13 | case LOGOUT_CURRENT_USER:
14 | return _nullSession;
15 | default:
16 | return state;
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/.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 all logfiles and tempfiles.
11 | /log/*
12 | /tmp/*
13 | !/log/.keep
14 | !/tmp/.keep
15 |
16 | /node_modules
17 | /yarn-error.log
18 |
19 | .byebug_history
20 |
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | const stateShape = {
2 | entities: {
3 | images: {
4 | byId: {
5 | 1: {
6 | id: 1,
7 | image_url: 'something.com',
8 | tagIds: [1]
9 | },
10 | 2: {
11 | id: 2,
12 | image_url: 'something.com',
13 | }
14 | },
15 | ids: [2, 1]
16 | },
17 | tags: {
18 | byId: {
19 | 1: {
20 | id: 1,
21 | name: 'themed tag'
22 | }
23 | },
24 | ids: [1]
25 | }
26 | },
27 | session: {}
28 | };
29 |
--------------------------------------------------------------------------------
/frontend/reducers/chirps.js:
--------------------------------------------------------------------------------
1 | import { RECEIVE_CHIRPS, RECEIVE_SINGLE_CHIRP } from '../actions/chirps';
2 |
3 | export default (state = {}, action) => {
4 | Object.freeze(state);
5 | switch (action.type) {
6 | case RECEIVE_CHIRPS:
7 | const chirps = {};
8 | action.chirps.forEach(chirp => {
9 | chirps[chirp.id] = chirp;
10 | });
11 | return chirps;
12 | case RECEIVE_SINGLE_CHIRP:
13 | return Object.assign({}, state, { [action.chirp.id]: action.chirp });
14 | default:
15 | return state;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/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]
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 |
--------------------------------------------------------------------------------
/bin/spring:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | # This file loads spring without using Bundler, in order to be fast.
4 | # It gets overwritten when you run the `spring binstub` command.
5 |
6 | unless defined?(Spring)
7 | require 'rubygems'
8 | require 'bundler'
9 |
10 | lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
11 | spring = lockfile.specs.detect { |spec| spec.name == "spring" }
12 | if spring
13 | Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
14 | gem 'spring', spring.version
15 | require 'spring/binstub'
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | entry: './frontend/bluebird.jsx',
5 | output: {
6 | path: path.resolve(__dirname, 'app', 'assets', 'javascripts'),
7 | filename: 'bundle.js'
8 | },
9 | module: {
10 | loaders: [
11 | {
12 | test: [/\.jsx?$/],
13 | exclude: /node_modules/,
14 | loader: 'babel-loader',
15 | query: {
16 | presets: ['es2015', 'react']
17 | }
18 | }
19 | ]
20 | },
21 | resolve: {
22 | extensions: ['.js', '.jsx', '*'],
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/app/controllers/api/likes_controller.rb:
--------------------------------------------------------------------------------
1 | class Api::LikesController < ApplicationController
2 | def create
3 | @like = Like.new
4 | @like.user_id = current_user.id
5 | @like.chirp_id = params[:id]
6 | if @like.save
7 | @chirp = @like.chirp
8 | render 'api/chirps/show'
9 | else
10 | render json: @like.errors.full_messages, status: 401
11 | end
12 | end
13 |
14 | def destroy
15 | @like = Like.find_by(user_id: current_user.id, chirp_id: params[:id])
16 | @like.destroy
17 | @chirp = @like.chirp
18 | render 'api/chirps/show'
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/frontend/components/chirps/chirp_item.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default ({ chirp, likeChirp, unLikeChirp }) => {
4 | let likeButtonText = "You don't like this.";
5 | let likeButtonAction = () => likeChirp(chirp.id);
6 | if (chirp.liked_by_current_user) {
7 | likeButtonText = "You like this";
8 | likeButtonAction = () => unLikeChirp(chirp.id);
9 | }
10 | return (
11 |
12 |
{chirp.body}
13 |
Likes: {chirp.likes}
14 |
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "BlueBird",
3 | "private": true,
4 | "dependencies": {
5 | "babel-core": "^6.26.0",
6 | "babel-loader": "^7.1.2",
7 | "babel-preset-es2015": "^6.24.1",
8 | "babel-preset-react": "^6.24.1",
9 | "react": "^15.6.1",
10 | "react-dom": "^15.6.1",
11 | "react-redux": "^5.0.6",
12 | "react-router-dom": "^4.2.2",
13 | "redux": "^3.7.2",
14 | "redux-devtools-extension": "^2.13.2",
15 | "redux-logger": "^3.0.6",
16 | "webpack": "^3.5.6"
17 | },
18 | "devDependencies": {
19 | "redux-devtools-extension": "^2.13.2"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/models/follow.rb:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | #
3 | # Table name: follows
4 | #
5 | # id :integer not null, primary key
6 | # follower_id :integer not null
7 | # followee_id :integer not null
8 | # created_at :datetime not null
9 | # updated_at :datetime not null
10 | #
11 |
12 | class Follow < ApplicationRecord
13 |
14 | belongs_to :follower,
15 | primary_key: :id,
16 | foreign_key: :follower_id,
17 | class_name: :User
18 |
19 | belongs_to :followee,
20 | primary_key: :id,
21 | foreign_key: :followee_id,
22 | class_name: :User
23 | end
24 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 |
3 | # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
4 | namespace :api, defaults: { format: :json } do
5 | resources :users do
6 | resources :chirps, only: [:index]
7 | end
8 |
9 | resource :session, only: [:new, :create, :destroy]
10 |
11 | post '/search', to: 'users#search'
12 |
13 | resources :chirps
14 | resources :likes, only: [:create]
15 | delete '/likes', to: 'likes#destroy'
16 | resources :follows, only: [:create, :destroy]
17 | end
18 | root to: 'root#root'
19 | end
20 |
--------------------------------------------------------------------------------
/frontend/bluebird.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import createStore from './store/store';
4 | import Root from './components/root';
5 |
6 | document.addEventListener('DOMContentLoaded', () => {
7 | const root = document.getElementById('root');
8 | let preloadedState = undefined;
9 | if (window.currentUser) {
10 | preloadedState = {
11 | session: {
12 | currentUser: window.currentUser
13 | }
14 | };
15 | }
16 | const store = createStore(preloadedState);
17 | // const store = createStore();
18 |
19 | ReactDOM.render(, root);
20 | })
--------------------------------------------------------------------------------
/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | BlueBird
5 | <%= csrf_meta_tags %>
6 |
7 | <%= stylesheet_link_tag 'application', media: 'all' %>
8 | <%= javascript_include_tag 'application' %>
9 | <% if current_user %>
10 |
17 | <% end %>
18 |
19 |
20 |
21 | <%= yield %>
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/controllers/likes_controller.rb:
--------------------------------------------------------------------------------
1 | # This class doesn't make a whole lot of sense unless there's a logged
2 | # in user. We're going to go ahead and skip the views for this for now.
3 |
4 | class LikesController < ApplicationController
5 | def create
6 | @like = Like.new
7 | @like.user_id = current_user.id
8 | @like.chirp_id = params[:id]
9 | unless @like.save
10 | flash[:errors] = @like.errors.full_messages
11 | end
12 | redirect_to chirp_url(params[:id])
13 | end
14 |
15 | def destroy
16 | @like = Like.find(params[:id])
17 | @like.destroy
18 | redirect_to chirp_url(@like.chirp_id)
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/frontend/components/chirps/chirp_index_container.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ChirpIndex from './chirp_index';
3 | import { fetchChirps, likeChirp, unLikeChirp } from '../../actions/chirps';
4 | import { connect } from 'react-redux';
5 |
6 | const mapStateToProps = (state) => ({
7 | chirps: Object.keys(state.entities.chirps).map(key => state.entities.chirps[key])
8 | });
9 |
10 | const mapDispatchToProps = (dispatch) => ({
11 | fetchChirps: () => dispatch(fetchChirps()),
12 | likeChirp: id => dispatch(likeChirp(id)),
13 | unLikeChirp: id => dispatch(unLikeChirp(id))
14 | });
15 |
16 | export default connect(mapStateToProps, mapDispatchToProps)(ChirpIndex);
17 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | require_relative 'boot'
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 BlueBird
10 | class Application < Rails::Application
11 | # Initialize configuration defaults for originally generated Rails version.
12 | config.load_defaults 5.1
13 |
14 | # Settings in config/environments/* take precedence over those specified here.
15 | # Application configuration should go into files in config/initializers
16 | # -- all .rb files in that directory are automatically loaded.
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/frontend/components/nav_bar/nav_bar.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'react-router-dom';
3 |
4 | export default ({ currentUser, logout }) => {
5 | const display = currentUser ? (
6 |
7 |
Welcome {currentUser.username}!
8 |
9 |
10 | ) : (
11 |
12 | Sign Up
13 | Log In
14 |
15 | );
16 | return (
17 |
18 |
BLUEBIRD
19 |
20 | {display}
21 |
22 |
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Version of your assets, change this if you want to expire all your assets.
4 | Rails.application.config.assets.version = '1.0'
5 |
6 | # Add additional assets to the asset load path.
7 | # Rails.application.config.assets.paths << Emoji.images_path
8 | # Add Yarn node_modules folder to the asset load path.
9 | Rails.application.config.assets.paths << Rails.root.join('node_modules')
10 |
11 | # Precompile additional assets.
12 | # application.js, application.css, and all non-JS/CSS in the app/assets
13 | # folder are already added.
14 | # Rails.application.config.assets.precompile += %w( admin.js admin.css )
15 |
--------------------------------------------------------------------------------
/test/fixtures/chirps.yml:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | #
3 | # Table name: chirps
4 | #
5 | # id :integer not null, primary key
6 | # body :text not null
7 | # author_id :integer not null
8 | # created_at :datetime not null
9 | # updated_at :datetime not null
10 | #
11 |
12 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
13 |
14 | # This model initially had no columns defined. If you add columns to the
15 | # model remove the '{}' from the fixture names and add the columns immediately
16 | # below each fixture, per the syntax in the comments below
17 | #
18 | one: {}
19 | # column: value
20 | #
21 | two: {}
22 | # column: value
23 |
--------------------------------------------------------------------------------
/test/fixtures/likes.yml:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | #
3 | # Table name: likes
4 | #
5 | # id :integer not null, primary key
6 | # user_id :integer not null
7 | # chirp_id :integer not null
8 | # created_at :datetime not null
9 | # updated_at :datetime not null
10 | #
11 |
12 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
13 |
14 | # This model initially had no columns defined. If you add columns to the
15 | # model remove the '{}' from the fixture names and add the columns immediately
16 | # below each fixture, per the syntax in the comments below
17 | #
18 | one: {}
19 | # column: value
20 | #
21 | two: {}
22 | # column: value
23 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test/fixtures/follows.yml:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | #
3 | # Table name: follows
4 | #
5 | # id :integer not null, primary key
6 | # follower_id :integer not null
7 | # followee_id :integer not null
8 | # created_at :datetime not null
9 | # updated_at :datetime not null
10 | #
11 |
12 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
13 |
14 | # This model initially had no columns defined. If you add columns to the
15 | # model remove the '{}' from the fixture names and add the columns immediately
16 | # below each fixture, per the syntax in the comments below
17 | #
18 | one: {}
19 | # column: value
20 | #
21 | two: {}
22 | # column: value
23 |
--------------------------------------------------------------------------------
/frontend/utils/session.js:
--------------------------------------------------------------------------------
1 | export const postUser = (user) => {
2 | return $.ajax({
3 | url: '/api/users',
4 | method: 'POST',
5 | data: { user }
6 | });
7 | };
8 |
9 | // const user = {
10 | // id: 1,
11 | // username: "",
12 | // email: "",
13 | // password: "password"
14 | // }
15 |
16 | // const data = {
17 | // user: {
18 | // id: 1,
19 | // username: "",
20 | // email: "",
21 | // password: "password"
22 | // }
23 | // }
24 |
25 | export const postSession = (user) => {
26 | return $.ajax({
27 | url: '/api/session',
28 | method: 'POST',
29 | data: { user }
30 | });
31 | };
32 |
33 | export const deleteSession = () => {
34 | return $.ajax({
35 | url: '/api/session',
36 | method: 'DELETE'
37 | });
38 | };
39 |
--------------------------------------------------------------------------------
/app/controllers/sessions_controller.rb:
--------------------------------------------------------------------------------
1 | class SessionsController < ApplicationController
2 | def new
3 | render :new
4 | end
5 |
6 | def create
7 | # Find user by credentials
8 | @user = User.find_by_credentials(params[:user][:username], params[:user][:password])
9 | # Flash errors, if any.
10 | # Render :new if invalid credentials (give the user another chance to login)
11 | if @user.nil?
12 | flash.now[:errors] = ['Invalid username or password.']
13 | render :new
14 | else
15 | # Log them in and redirect them if we find them
16 | login!(@user)
17 | redirect_to user_url(@user)
18 | end
19 |
20 | end
21 |
22 | def destroy
23 | logout!
24 | # redirect to login page
25 | redirect_to new_session_url
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/app/assets/javascripts/application.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into application.js, which will include all the files
2 | // listed below.
3 | //
4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
5 | // vendor/assets/javascripts directory can be referenced here using a relative path.
6 | //
7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 | // compiled file. JavaScript code in this file should be added after the last require_* statement.
9 | //
10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11 | // about supported directives.
12 | //
13 | //= require jquery
14 | //= require jquery_ujs
15 | //= require rails-ujs
16 | //= require_tree .
17 |
--------------------------------------------------------------------------------
/frontend/components/chirps/chirp_index.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ChirpItem from './chirp_item';
3 |
4 | class ChirpIndex extends React.Component {
5 | constructor(props) {
6 | super(props);
7 | }
8 |
9 | componentDidMount() {
10 | this.props.fetchChirps();
11 | }
12 |
13 | render() {
14 | const { chirps } = this.props;
15 | return (
16 |
If you are the application owner check the logs for more information.
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Do not eager load code on boot. This avoids loading your whole application
11 | # just for the purpose of running a single test. If you are using a tool that
12 | # preloads Rails for running tests, you may have to set it to true.
13 | config.eager_load = false
14 |
15 | # Configure public file server for tests with Cache-Control for performance.
16 | config.public_file_server.enabled = true
17 | config.public_file_server.headers = {
18 | 'Cache-Control' => "public, max-age=#{1.hour.seconds.to_i}"
19 | }
20 |
21 | # Show full error reports and disable caching.
22 | config.consider_all_requests_local = true
23 | config.action_controller.perform_caching = false
24 |
25 | # Raise exceptions instead of rendering exception templates.
26 | config.action_dispatch.show_exceptions = false
27 |
28 | # Disable request forgery protection in test environment.
29 | config.action_controller.allow_forgery_protection = false
30 | config.action_mailer.perform_caching = false
31 |
32 | # Tell Action Mailer not to deliver emails to the real world.
33 | # The :test delivery method accumulates sent emails in the
34 | # ActionMailer::Base.deliveries array.
35 | config.action_mailer.delivery_method = :test
36 |
37 | # Print deprecation notices to the stderr.
38 | config.active_support.deprecation = :stderr
39 |
40 | # Raises error for missing translations
41 | # config.action_view.raise_on_missing_translations = true
42 | end
43 |
--------------------------------------------------------------------------------
/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The change you wanted was rejected.
62 |
Maybe you tried to change something you didn't have access to.
63 |
64 |
If you are the application owner check the logs for more information.
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The page you were looking for doesn't exist.
62 |
You may have mistyped the address or the page may have moved.
63 |
64 |
If you are the application owner check the logs for more information.
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Rails.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.
13 | config.consider_all_requests_local = true
14 |
15 | # Enable/disable caching. By default caching is disabled.
16 | if Rails.root.join('tmp/caching-dev.txt').exist?
17 | config.action_controller.perform_caching = true
18 |
19 | config.cache_store = :memory_store
20 | config.public_file_server.headers = {
21 | 'Cache-Control' => "public, max-age=#{2.days.seconds.to_i}"
22 | }
23 | else
24 | config.action_controller.perform_caching = false
25 |
26 | config.cache_store = :null_store
27 | end
28 |
29 | # Don't care if the mailer can't send.
30 | config.action_mailer.raise_delivery_errors = false
31 |
32 | config.action_mailer.perform_caching = false
33 |
34 | # Print deprecation notices to the Rails logger.
35 | config.active_support.deprecation = :log
36 |
37 | # Raise an error on page load if there are pending migrations.
38 | config.active_record.migration_error = :page_load
39 |
40 | # Debug mode disables concatenation and preprocessing of assets.
41 | # This option may cause significant delays in view rendering with a large
42 | # number of complex assets.
43 | config.assets.debug = true
44 |
45 | # Suppress logger output for asset requests.
46 | config.assets.quiet = true
47 |
48 | # Raises error for missing translations
49 | # config.action_view.raise_on_missing_translations = true
50 |
51 | # Use an evented file watcher to asynchronously detect changes in source code,
52 | # routes, locales, etc. This feature depends on the listen gem.
53 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker
54 | end
55 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | git_source(:github) do |repo_name|
4 | repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
5 | "https://github.com/#{repo_name}.git"
6 | end
7 |
8 |
9 |
10 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
11 | gem 'rails', '~> 5.1.3'
12 | # Use postgresql as the database for Active Record
13 | gem 'pg', '~> 0.18'
14 | # Use Puma as the app server
15 | gem 'puma', '~> 3.7'
16 | # Use SCSS for stylesheets
17 | gem 'sass-rails', '~> 5.0'
18 | # Use Uglifier as compressor for JavaScript assets
19 | gem 'uglifier', '>= 1.3.0'
20 | # See https://github.com/rails/execjs#readme for more supported runtimes
21 | # gem 'therubyracer', platforms: :ruby
22 |
23 | # Use CoffeeScript for .coffee assets and views
24 | gem 'coffee-rails', '~> 4.2'
25 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
26 | gem 'jbuilder', '~> 2.5'
27 | # Use Redis adapter to run Action Cable in production
28 | # gem 'redis', '~> 3.0'
29 | # Use ActiveModel has_secure_password
30 | gem 'bcrypt', '~> 3.1.7'
31 |
32 | gem 'jquery-rails'
33 |
34 | # Use Capistrano for deployment
35 | # gem 'capistrano-rails', group: :development
36 |
37 | group :development, :test do
38 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console
39 | gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
40 | # Adds support for Capybara system testing and selenium driver
41 | gem 'capybara', '~> 2.13'
42 | gem 'selenium-webdriver'
43 | gem 'pry-rails'
44 | gem 'annotate'
45 | gem 'faker'
46 | end
47 |
48 | group :development do
49 | # Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
50 | gem 'web-console', '>= 3.3.0'
51 | gem 'listen', '>= 3.0.5', '< 3.2'
52 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
53 | gem 'spring'
54 | gem 'spring-watcher-listen', '~> 2.0.0'
55 | end
56 |
57 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
58 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
59 |
--------------------------------------------------------------------------------
/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 rails db:seed command (or created alongside the database with db:setup).
3 | #
4 | # Examples:
5 | #
6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
7 | # Character.create(name: 'Luke', movie: movies.first)
8 |
9 | User.destroy_all
10 | Chirp.destroy_all
11 | Like.destroy_all
12 |
13 | user1 = User.create(username: Faker::Name.name, email: Faker::Internet.email, password: 'password')
14 | user2 = User.create(username: Faker::Name.name, email: Faker::Internet.email, password: 'password')
15 | user3 = User.create(username: Faker::Name.name, email: Faker::Internet.email, password: 'password')
16 | user4 = User.create(username: Faker::Name.name, email: Faker::Internet.email, password: 'password')
17 | user5 = User.create(username: Faker::Name.name, email: Faker::Internet.email, password: 'password')
18 | user6 = User.create(username: Faker::Name.name, email: Faker::Internet.email, password: 'password')
19 | user7 = User.create(username: Faker::Name.name, email: Faker::Internet.email, password: 'password')
20 | user8 = User.create(username: Faker::Name.name, email: Faker::Internet.email, password: 'password')
21 | user9 = User.create(username: Faker::Name.name, email: Faker::Internet.email, password: 'password')
22 |
23 | chirp1 = Chirp.create(body: Faker::RickAndMorty.quote, author_id: user1.id)
24 | chirp2 = Chirp.create(body: Faker::RickAndMorty.quote, author_id: user1.id)
25 | chirp3 = Chirp.create(body: Faker::RickAndMorty.quote, author_id: user1.id)
26 | chirp4 = Chirp.create(body: Faker::RickAndMorty.quote, author_id: user2.id)
27 | chirp5 = Chirp.create(body: Faker::RickAndMorty.quote, author_id: user2.id)
28 | chirp6 = Chirp.create(body: Faker::RickAndMorty.quote, author_id: user2.id)
29 |
30 | Like.create(user_id: user3.id, chirp_id: chirp1.id)
31 | Like.create(user_id: user4.id, chirp_id: chirp2.id)
32 | Like.create(user_id: user5.id, chirp_id: chirp3.id)
33 | Like.create(user_id: user3.id, chirp_id: chirp3.id)
34 | Like.create(user_id: user4.id, chirp_id: chirp1.id)
35 | Like.create(user_id: user5.id, chirp_id: chirp2.id)
36 |
--------------------------------------------------------------------------------
/db/schema.rb:
--------------------------------------------------------------------------------
1 | # This file is auto-generated from the current state of the database. Instead
2 | # of editing this file, please use the migrations feature of Active Record to
3 | # incrementally modify your database, and then regenerate this schema definition.
4 | #
5 | # Note that this schema.rb definition is the authoritative source for your
6 | # database schema. If you need to create the application database on another
7 | # system, you should be using db:schema:load, not running all the migrations
8 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 | # you'll amass, the slower it'll run and the greater likelihood for issues).
10 | #
11 | # It's strongly recommended that you check this file into your version control system.
12 |
13 | ActiveRecord::Schema.define(version: 20170828221731) do
14 |
15 | # These are extensions that must be enabled in order to support this database
16 | enable_extension "plpgsql"
17 |
18 | create_table "chirps", force: :cascade do |t|
19 | t.text "body", null: false
20 | t.integer "author_id", null: false
21 | t.datetime "created_at", null: false
22 | t.datetime "updated_at", null: false
23 | t.index ["author_id"], name: "index_chirps_on_author_id"
24 | end
25 |
26 | create_table "follows", force: :cascade do |t|
27 | t.integer "follower_id", null: false
28 | t.integer "followee_id", null: false
29 | t.datetime "created_at", null: false
30 | t.datetime "updated_at", null: false
31 | t.index ["followee_id"], name: "index_follows_on_followee_id"
32 | t.index ["follower_id"], name: "index_follows_on_follower_id"
33 | end
34 |
35 | create_table "likes", force: :cascade do |t|
36 | t.integer "user_id", null: false
37 | t.integer "chirp_id", null: false
38 | t.datetime "created_at", null: false
39 | t.datetime "updated_at", null: false
40 | end
41 |
42 | create_table "users", force: :cascade do |t|
43 | t.string "username", null: false
44 | t.string "email"
45 | t.string "password_digest"
46 | t.string "session_token"
47 | t.index ["session_token"], name: "index_users_on_session_token"
48 | t.index ["username"], name: "index_users_on_username", unique: true
49 | end
50 |
51 | end
52 |
--------------------------------------------------------------------------------
/wiki/bluebird_dashboard_page.xml:
--------------------------------------------------------------------------------
1 | 7VxRc6M2EP41nrk+5AYQEPwY55I0M0mTmUznrk8d2ShGDUaukGO7v74SIBuQbGMHsHGShztYYUl8+nZXK63ogevJ4o7CafBIfBT2LMNf9MCPnmV5psf/FYJlKrBNKxWMKfZTkbkWvOD/UCY0MukM+yguPMgICRmeFoUjEkVoxAoySCmZFx97JWGx1SkcI0XwMoKhKv2JfRZkr+UYa/nvCI8D2bJpZCVDOHobUzKLsvZ6FnhN/tLiCZR1Zc/HAfTJPCcCNz1wTQlh6dVkcY1CAa2ELf3d7YbSVb8piliVH4D0B+8wnCHZ46RfbCmxSN4GieeNHhjMA8zQyxSOROmcDz6XBWwS8juTX6rtZ116R5ShRU6U9ecOkQlidMkfkaUgw2a5Aje9n69HwpF4B7lRABJUmI3+eFX3GgF+kYGgB8Q+I0CcGvBwNXi4IW9g8Er4G+WBcf+dEVlwESc6fcUfMI3pYl3Ir8bi/xc8jnjh04zJ+nhP0irTB7bAbrYCu+OWYLccBXbbUVGvg4WXCuoDfjWUUMVTGEmcMPVzCOZLFAT5i7MiTDGj5A1dk5BQLolIhMT44TAsiWAohgv8GHE4EZcPBIyY28urrGCCfV80ox2XGgYDSKS3DMalRgXqGAxPARL53Ftkt4SygIxJBMObtXRQtBE5xNECs1+ZWFz/Ja6/O/zuH8TYMnOFcMYIF63rfiBkuovaMZnRUdbDfuY0IR0jVrBsou9bEacohAy/Fz3hR/DrK2T+A74PID0nfrr93cbCaYif0h1s81ko8q/EvGgNmQ/jYGVNdQT9bhhmjqQXQtDPBM+IYt5PAXXC5EqctD2VlKAiKXfAKGWVuZu18Exw4sTkGHvFUbRNp1hF+jrZr/LTqlJFVsllA7dUUYqBUlEy1KvXrjb6pjrYHzBPEW/4V/6mIQMlA4KChfKOZaJkb3IqdMvn4OisbNSlUWK30aKNAt1kqX24yaqfpGps8ghx9Cxi2TOiadmVWq4a7jQ11ZP2Pgfxw9Pd0znBazoVwpqm4NVFk0cO81ZcknhcqnRbvXztgFx20yxqZnJybI9gFz2FVX/GiL4gSEfBOamu6+2mqtcUU9UobovqVlgYW618bo0f9tBjs+Q2DBUcoDdsNcBjVYjBjgxPcQHF0iwiAqCBBzg1oGN2DR1bdYrNoaMGHyeOjtcmd+reomgaHWC2yZ269ysaR8dpkzvqdP7E0fEqcqe8MHUQOq4CRhcmn3JzpDD5zGYn7U8+NVs11wGm03uO0kLB91iTz7p5W56JWv32YvR692OqUnPzvk010mo2ZOrfkdEvRjulvTMArGIVGxajryiFy9xjU/FAvLkd1y6SArhevrp9n+cXaQ8OXRnXbDytVfOeocn5qmdpTQM4nqKe/YbUE2giIXB18dsWx1thoad2x2uVDJhu0qZDqAa/C9RoaMiv/p6KzCV2tqS03DLkKimb8hnS4mnSWHz8XsBbJqoI2C8yBEUaS4hemZrGUszI2J0M09flwojR52VDTP1YtITfkluR8YEoxSjemOCxEidvcWJpH3UTCDi7CWQ2tXQNdGHoqTIIhjEpEklgTxhk5ItMG8jkmC2SSY3aEw8QwPnb2SKu2H8N4o3Zf81CQAcmJbZq4BqblGxO9Dw9+/blISsaNa9ND6muhHzKaa0G88bMmrrz2QWzplvkbMqs6bYtv8xat1SsbNaA3BNqw6zZ6nrGZzRrOsybMmu2Zrv49M3a6vhRC2bN/lrP6L6KKWZNs0rbnFlT1zM+pVnTYN6YWdPs1XfArDntzdbsjoTpVhEhzeZnYwipYfrnUNvdkDemtmpc++Vru0Yg4JQI5PVb9LWaMH3PQ9SebuzvMAtmw57oogsnArZoGKe5xlVEDzh6Q/59dHAFj8s4GbWKB7gP4FLPArfJ34cJVQOHyufwbU2Gsf7DBHVwqEL+9R6HPDckaxmGJQWVj3gedIKvpfOcm0Zs3/OcrtyzX/kfr1hRfec55at3Z29IKL3MvtJ8gGRvPbPLxxxaPOvvaJYerA9+i6II1gbrtgEkDZRbkklLuLmqj9POS60acKv1fOd++aIlY7MzF09OBfKGy2krX1Q2niPYtwjNuWQkctPE3G3GGInUmOckdL0Omh7vEJOjRuA3PlbDppNUb6d0fFu3f65NFe/XANyJporvrfqORvXttlRfXd34hhL6fRrdd93SSSLNmvnq81Yf1H5+u/6OWjoRW3+rDtz8Dw==
--------------------------------------------------------------------------------
/config/puma.rb:
--------------------------------------------------------------------------------
1 | # Puma can serve each request in a thread from an internal thread pool.
2 | # The `threads` method setting takes two numbers: a minimum and maximum.
3 | # Any libraries that use thread pools should be configured to match
4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum
5 | # and maximum; this matches the default thread size of Active Record.
6 | #
7 | threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
8 | threads threads_count, threads_count
9 |
10 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
11 | #
12 | port ENV.fetch("PORT") { 3000 }
13 |
14 | # Specifies the `environment` that Puma will run in.
15 | #
16 | environment ENV.fetch("RAILS_ENV") { "development" }
17 |
18 | # Specifies the number of `workers` to boot in clustered mode.
19 | # Workers are forked webserver processes. If using threads and workers together
20 | # the concurrency of the application would be max `threads` * `workers`.
21 | # Workers do not work on JRuby or Windows (both of which do not support
22 | # processes).
23 | #
24 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 }
25 |
26 | # Use the `preload_app!` method when specifying a `workers` number.
27 | # This directive tells Puma to first boot the application and load code
28 | # before forking the application. This takes advantage of Copy On Write
29 | # process behavior so workers use less memory. If you use this option
30 | # you need to make sure to reconnect any threads in the `on_worker_boot`
31 | # block.
32 | #
33 | # preload_app!
34 |
35 | # If you are preloading your application and using Active Record, it's
36 | # recommended that you close any connections to the database before workers
37 | # are forked to prevent connection leakage.
38 | #
39 | # before_fork do
40 | # ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord)
41 | # end
42 |
43 | # The code in the `on_worker_boot` will be called if you are using
44 | # clustered mode by specifying a number of `workers`. After each worker
45 | # process is booted, this block will be run. If you are using the `preload_app!`
46 | # option, you will want to use this block to reconnect to any threads
47 | # or connections that may have been created at application boot, as Ruby
48 | # cannot share connections between processes.
49 | #
50 | # on_worker_boot do
51 | # ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
52 | # end
53 | #
54 |
55 | # Allow puma to be restarted by `rails restart` command.
56 | plugin :tmp_restart
57 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/application.scss:
--------------------------------------------------------------------------------
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, or any plugin's
6 | * vendor/assets/stylesheets directory 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 bottom of the
9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10 | * files in this directory. Styles in this file should be added after the last require_* statement.
11 | * It is generally better to create a new file per style scope.
12 | *
13 | *= require_tree .
14 | *= require_self
15 | */
16 |
17 | html, body, div {
18 | padding: 0;
19 | margin: 0;
20 | font-family: sans-serif;
21 | }
22 |
23 | .hero-img-frame {
24 | position: absolute;
25 | width: 100%;
26 | max-height: 500px;
27 | overflow: hidden;
28 | display: flex;
29 | justify-content: center;
30 | align-items: center;
31 | z-index: -1;
32 | }
33 |
34 | .hero-img {
35 | width: 100%;
36 | }
37 |
38 | .home {
39 | min-height: 400px;
40 | display: flex;
41 | justify-content: center;
42 | align-items: flex-end;
43 | h1 {
44 | height: 100%;
45 | z-index: 1;
46 | color: white;
47 | text-shadow: 1px 1px 15px black;
48 | text-align: center;
49 | width: 100%;
50 | }
51 | }
52 |
53 | .nav-bar {
54 | display: flex;
55 | justify-content: space-between;
56 | padding: 20px;
57 | background: lightblue;
58 | align-items: center;
59 | .btn {
60 | background-color: white;
61 | padding: 10px;
62 | box-shadow: 3px 3px 3px darkblue;
63 | text-decoration: none;
64 | }
65 | .btn:hover {
66 | background-color: rgb(240, 240, 240);
67 | box-shadow: 1px 1px 1px darkblue;
68 | }
69 | }
70 |
71 | .session-form {
72 | display: flex;
73 | flex-direction: column;
74 | width: 100%;
75 | height: 90vh;
76 | justify-content: center;
77 | align-items: center;
78 | form {
79 | height: 300px;
80 | width: 300px;
81 | background: rgb(240, 240, 240);
82 | display: flex;
83 | flex-direction: column;
84 | justify-content: center;
85 | align-items: center;
86 | }
87 | label {
88 | padding: 10px;
89 | display: block;
90 | }
91 | button {
92 | display: block;
93 | padding: 10px;
94 | margin: 20px;
95 | }
96 | }
--------------------------------------------------------------------------------
/wiki/bluebird_user_search.xml:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/app/models/user.rb:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | #
3 | # Table name: users
4 | #
5 | # id :integer not null, primary key
6 | # username :string not null
7 | # email :string
8 | # password_digest :string
9 | # session_token :string
10 | #
11 |
12 | class User < ApplicationRecord
13 | # This makes it so we can validate our password length, without storing it in the DB
14 | attr_reader :password
15 |
16 | validates :username, presence: true, uniqueness: true
17 | validates :password_digest, :session_token, presence: true
18 | validates :password, length: { minimum: 6 }, allow_nil: true
19 |
20 | # This allows us to run methods before running validations
21 | # In this case, we need to have a session_token when a user is first created
22 | after_initialize :ensure_session_token
23 |
24 | has_many :likes,
25 | primary_key: :id,
26 | foreign_key: :user_id,
27 | class_name: :Like
28 |
29 | has_many :liked_chirps,
30 | through: :likes,
31 | source: :chirp
32 |
33 | has_many :chirps,
34 | primary_key: :id,
35 | foreign_key: :author_id,
36 | class_name: :Chirp
37 |
38 | has_many :fanships,
39 | primary_key: :id,
40 | foreign_key: :followee_id,
41 | class_name: :Follow
42 |
43 | has_many :followships,
44 | primary_key: :id,
45 | foreign_key: :follower_id,
46 | class_name: :Follow
47 |
48 | has_many :followers,
49 | through: :fanships,
50 | source: :follower
51 |
52 | has_many :followees,
53 | through: :followships,
54 | source: :followee
55 |
56 | # Class method for finding a user ONLY if we have the correct username and password
57 | def self.find_by_credentials(username, password)
58 | user = User.find_by(username: username)
59 | return nil unless user
60 | user.is_password?(password) ? user : nil
61 | end
62 |
63 | def password=(password)
64 | # Set temporary instance variable so that we can validate length
65 | @password = password
66 | # Create a password_digest so that we do not have to store the plain-text password in our DB
67 | self.password_digest = BCrypt::Password.create(password)
68 | end
69 |
70 | def is_password?(password)
71 | # Use BCrypt's built-in method for checking if the password provided is the user's password
72 | BCrypt::Password.new(self.password_digest).is_password?(password)
73 | end
74 |
75 | def ensure_session_token
76 | # Generate the initial session_token so that we pass the validation
77 | # This method runs right after the model is initialized, before any validations are run
78 | self.session_token ||= SecureRandom.urlsafe_base64
79 | end
80 |
81 | def reset_session_token!
82 | # When a user logs out, we want to scramble their session_token so that bad people cannot use the old one
83 | self.session_token = SecureRandom.urlsafe_base64
84 | self.save
85 | self.session_token
86 | end
87 | end
88 |
--------------------------------------------------------------------------------
/config/database.yml:
--------------------------------------------------------------------------------
1 | # PostgreSQL. Versions 9.1 and up are supported.
2 | #
3 | # Install the pg driver:
4 | # gem install pg
5 | # On OS X with Homebrew:
6 | # gem install pg -- --with-pg-config=/usr/local/bin/pg_config
7 | # On OS X with MacPorts:
8 | # gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
9 | # On Windows:
10 | # gem install pg
11 | # Choose the win32 build.
12 | # Install PostgreSQL and put its /bin directory on your path.
13 | #
14 | # Configure Using Gemfile
15 | # gem 'pg'
16 | #
17 | default: &default
18 | adapter: postgresql
19 | encoding: unicode
20 | # For details on connection pooling, see Rails configuration guide
21 | # http://guides.rubyonrails.org/configuring.html#database-pooling
22 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
23 |
24 | development:
25 | <<: *default
26 | database: BlueBird_development
27 |
28 | # The specified database role being used to connect to postgres.
29 | # To create additional roles in postgres see `$ createuser --help`.
30 | # When left blank, postgres will use the default role. This is
31 | # the same name as the operating system user that initialized the database.
32 | #username: BlueBird
33 |
34 | # The password associated with the postgres role (username).
35 | #password:
36 |
37 | # Connect on a TCP socket. Omitted by default since the client uses a
38 | # domain socket that doesn't need configuration. Windows does not have
39 | # domain sockets, so uncomment these lines.
40 | #host: localhost
41 |
42 | # The TCP port the server listens on. Defaults to 5432.
43 | # If your server runs on a different port number, change accordingly.
44 | #port: 5432
45 |
46 | # Schema search path. The server defaults to $user,public
47 | #schema_search_path: myapp,sharedapp,public
48 |
49 | # Minimum log levels, in increasing order:
50 | # debug5, debug4, debug3, debug2, debug1,
51 | # log, notice, warning, error, fatal, and panic
52 | # Defaults to warning.
53 | #min_messages: notice
54 |
55 | # Warning: The database defined as "test" will be erased and
56 | # re-generated from your development database when you run "rake".
57 | # Do not set this db to the same as development or production.
58 | test:
59 | <<: *default
60 | database: BlueBird_test
61 |
62 | # As with config/secrets.yml, you never want to store sensitive information,
63 | # like your database password, in your source code. If your source code is
64 | # ever seen by anyone, they now have access to your database.
65 | #
66 | # Instead, provide the password as a unix environment variable when you boot
67 | # the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
68 | # for a full rundown on how to provide these environment variables in a
69 | # production deployment.
70 | #
71 | # On Heroku and other platform providers, you may have a full connection URL
72 | # available as an environment variable. For example:
73 | #
74 | # DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
75 | #
76 | # You can use this database configuration with:
77 | #
78 | # production:
79 | # url: <%= ENV['DATABASE_URL'] %>
80 | #
81 | production:
82 | <<: *default
83 | database: BlueBird_production
84 | username: BlueBird
85 | password: <%= ENV['BLUEBIRD_DATABASE_PASSWORD'] %>
86 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # Code is not reloaded between requests.
5 | config.cache_classes = true
6 |
7 | # Eager load code on boot. This eager loads most of Rails and
8 | # your application in memory, allowing both threaded web servers
9 | # and those relying on copy on write to perform better.
10 | # Rake tasks automatically ignore this option for performance.
11 | config.eager_load = true
12 |
13 | # Full error reports are disabled and caching is turned on.
14 | config.consider_all_requests_local = false
15 | config.action_controller.perform_caching = true
16 |
17 | # Attempt to read encrypted secrets from `config/secrets.yml.enc`.
18 | # Requires an encryption key in `ENV["RAILS_MASTER_KEY"]` or
19 | # `config/secrets.yml.key`.
20 | config.read_encrypted_secrets = true
21 |
22 | # Disable serving static files from the `/public` folder by default since
23 | # Apache or NGINX already handles this.
24 | config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
25 |
26 | # Compress JavaScripts and CSS.
27 | config.assets.js_compressor = :uglifier
28 | # config.assets.css_compressor = :sass
29 |
30 | # Do not fallback to assets pipeline if a precompiled asset is missed.
31 | config.assets.compile = false
32 |
33 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
34 |
35 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
36 | # config.action_controller.asset_host = 'http://assets.example.com'
37 |
38 | # Specifies the header that your server uses for sending files.
39 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
40 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
41 |
42 | # Mount Action Cable outside main process or domain
43 | # config.action_cable.mount_path = nil
44 | # config.action_cable.url = 'wss://example.com/cable'
45 | # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
46 |
47 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
48 | # config.force_ssl = true
49 |
50 | # Use the lowest log level to ensure availability of diagnostic information
51 | # when problems arise.
52 | config.log_level = :debug
53 |
54 | # Prepend all log lines with the following tags.
55 | config.log_tags = [ :request_id ]
56 |
57 | # Use a different cache store in production.
58 | # config.cache_store = :mem_cache_store
59 |
60 | # Use a real queuing backend for Active Job (and separate queues per environment)
61 | # config.active_job.queue_adapter = :resque
62 | # config.active_job.queue_name_prefix = "BlueBird_#{Rails.env}"
63 | config.action_mailer.perform_caching = false
64 |
65 | # Ignore bad email addresses and do not raise email delivery errors.
66 | # Set this to true and configure the email server for immediate delivery to raise delivery errors.
67 | # config.action_mailer.raise_delivery_errors = false
68 |
69 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
70 | # the I18n.default_locale when a translation cannot be found).
71 | config.i18n.fallbacks = true
72 |
73 | # Send deprecation notices to registered listeners.
74 | config.active_support.deprecation = :notify
75 |
76 | # Use default logging formatter so that PID and timestamp are not suppressed.
77 | config.log_formatter = ::Logger::Formatter.new
78 |
79 | # Use a different logger for distributed setups.
80 | # require 'syslog/logger'
81 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
82 |
83 | if ENV["RAILS_LOG_TO_STDOUT"].present?
84 | logger = ActiveSupport::Logger.new(STDOUT)
85 | logger.formatter = config.log_formatter
86 | config.logger = ActiveSupport::TaggedLogging.new(logger)
87 | end
88 |
89 | # Do not dump schema after migrations.
90 | config.active_record.dump_schema_after_migration = false
91 | end
92 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | actioncable (5.1.3)
5 | actionpack (= 5.1.3)
6 | nio4r (~> 2.0)
7 | websocket-driver (~> 0.6.1)
8 | actionmailer (5.1.3)
9 | actionpack (= 5.1.3)
10 | actionview (= 5.1.3)
11 | activejob (= 5.1.3)
12 | mail (~> 2.5, >= 2.5.4)
13 | rails-dom-testing (~> 2.0)
14 | actionpack (5.1.3)
15 | actionview (= 5.1.3)
16 | activesupport (= 5.1.3)
17 | rack (~> 2.0)
18 | rack-test (~> 0.6.3)
19 | rails-dom-testing (~> 2.0)
20 | rails-html-sanitizer (~> 1.0, >= 1.0.2)
21 | actionview (5.1.3)
22 | activesupport (= 5.1.3)
23 | builder (~> 3.1)
24 | erubi (~> 1.4)
25 | rails-dom-testing (~> 2.0)
26 | rails-html-sanitizer (~> 1.0, >= 1.0.3)
27 | activejob (5.1.3)
28 | activesupport (= 5.1.3)
29 | globalid (>= 0.3.6)
30 | activemodel (5.1.3)
31 | activesupport (= 5.1.3)
32 | activerecord (5.1.3)
33 | activemodel (= 5.1.3)
34 | activesupport (= 5.1.3)
35 | arel (~> 8.0)
36 | activesupport (5.1.3)
37 | concurrent-ruby (~> 1.0, >= 1.0.2)
38 | i18n (~> 0.7)
39 | minitest (~> 5.1)
40 | tzinfo (~> 1.1)
41 | addressable (2.5.1)
42 | public_suffix (~> 2.0, >= 2.0.2)
43 | annotate (2.7.2)
44 | activerecord (>= 3.2, < 6.0)
45 | rake (>= 10.4, < 13.0)
46 | arel (8.0.0)
47 | bcrypt (3.1.11)
48 | bindex (0.5.0)
49 | builder (3.2.3)
50 | byebug (9.0.6)
51 | capybara (2.15.1)
52 | addressable
53 | mini_mime (>= 0.1.3)
54 | nokogiri (>= 1.3.3)
55 | rack (>= 1.0.0)
56 | rack-test (>= 0.5.4)
57 | xpath (~> 2.0)
58 | childprocess (0.7.1)
59 | ffi (~> 1.0, >= 1.0.11)
60 | coderay (1.1.1)
61 | coffee-rails (4.2.2)
62 | coffee-script (>= 2.2.0)
63 | railties (>= 4.0.0)
64 | coffee-script (2.4.1)
65 | coffee-script-source
66 | execjs
67 | coffee-script-source (1.12.2)
68 | concurrent-ruby (1.0.5)
69 | erubi (1.6.1)
70 | execjs (2.7.0)
71 | faker (1.8.3)
72 | i18n (~> 0.5)
73 | ffi (1.9.18)
74 | globalid (0.4.0)
75 | activesupport (>= 4.2.0)
76 | i18n (0.8.6)
77 | jbuilder (2.7.0)
78 | activesupport (>= 4.2.0)
79 | multi_json (>= 1.2)
80 | jquery-rails (4.3.1)
81 | rails-dom-testing (>= 1, < 3)
82 | railties (>= 4.2.0)
83 | thor (>= 0.14, < 2.0)
84 | listen (3.1.5)
85 | rb-fsevent (~> 0.9, >= 0.9.4)
86 | rb-inotify (~> 0.9, >= 0.9.7)
87 | ruby_dep (~> 1.2)
88 | loofah (2.0.3)
89 | nokogiri (>= 1.5.9)
90 | mail (2.6.6)
91 | mime-types (>= 1.16, < 4)
92 | method_source (0.8.2)
93 | mime-types (3.1)
94 | mime-types-data (~> 3.2015)
95 | mime-types-data (3.2016.0521)
96 | mini_mime (0.1.4)
97 | mini_portile2 (2.2.0)
98 | minitest (5.10.3)
99 | multi_json (1.12.1)
100 | nio4r (2.1.0)
101 | nokogiri (1.8.0)
102 | mini_portile2 (~> 2.2.0)
103 | pg (0.21.0)
104 | pry (0.10.4)
105 | coderay (~> 1.1.0)
106 | method_source (~> 0.8.1)
107 | slop (~> 3.4)
108 | pry-rails (0.3.6)
109 | pry (>= 0.10.4)
110 | public_suffix (2.0.5)
111 | puma (3.9.1)
112 | rack (2.0.3)
113 | rack-test (0.6.3)
114 | rack (>= 1.0)
115 | rails (5.1.3)
116 | actioncable (= 5.1.3)
117 | actionmailer (= 5.1.3)
118 | actionpack (= 5.1.3)
119 | actionview (= 5.1.3)
120 | activejob (= 5.1.3)
121 | activemodel (= 5.1.3)
122 | activerecord (= 5.1.3)
123 | activesupport (= 5.1.3)
124 | bundler (>= 1.3.0)
125 | railties (= 5.1.3)
126 | sprockets-rails (>= 2.0.0)
127 | rails-dom-testing (2.0.3)
128 | activesupport (>= 4.2.0)
129 | nokogiri (>= 1.6)
130 | rails-html-sanitizer (1.0.3)
131 | loofah (~> 2.0)
132 | railties (5.1.3)
133 | actionpack (= 5.1.3)
134 | activesupport (= 5.1.3)
135 | method_source
136 | rake (>= 0.8.7)
137 | thor (>= 0.18.1, < 2.0)
138 | rake (12.0.0)
139 | rb-fsevent (0.10.2)
140 | rb-inotify (0.9.10)
141 | ffi (>= 0.5.0, < 2)
142 | ruby_dep (1.5.0)
143 | rubyzip (1.2.1)
144 | sass (3.5.1)
145 | sass-listen (~> 4.0.0)
146 | sass-listen (4.0.0)
147 | rb-fsevent (~> 0.9, >= 0.9.4)
148 | rb-inotify (~> 0.9, >= 0.9.7)
149 | sass-rails (5.0.6)
150 | railties (>= 4.0.0, < 6)
151 | sass (~> 3.1)
152 | sprockets (>= 2.8, < 4.0)
153 | sprockets-rails (>= 2.0, < 4.0)
154 | tilt (>= 1.1, < 3)
155 | selenium-webdriver (3.5.1)
156 | childprocess (~> 0.5)
157 | rubyzip (~> 1.0)
158 | slop (3.6.0)
159 | spring (2.0.2)
160 | activesupport (>= 4.2)
161 | spring-watcher-listen (2.0.1)
162 | listen (>= 2.7, < 4.0)
163 | spring (>= 1.2, < 3.0)
164 | sprockets (3.7.1)
165 | concurrent-ruby (~> 1.0)
166 | rack (> 1, < 3)
167 | sprockets-rails (3.2.0)
168 | actionpack (>= 4.0)
169 | activesupport (>= 4.0)
170 | sprockets (>= 3.0.0)
171 | thor (0.19.4)
172 | thread_safe (0.3.6)
173 | tilt (2.0.8)
174 | tzinfo (1.2.3)
175 | thread_safe (~> 0.1)
176 | uglifier (3.2.0)
177 | execjs (>= 0.3.0, < 3)
178 | web-console (3.5.1)
179 | actionview (>= 5.0)
180 | activemodel (>= 5.0)
181 | bindex (>= 0.4.0)
182 | railties (>= 5.0)
183 | websocket-driver (0.6.5)
184 | websocket-extensions (>= 0.1.0)
185 | websocket-extensions (0.1.2)
186 | xpath (2.1.0)
187 | nokogiri (~> 1.3)
188 |
189 | PLATFORMS
190 | ruby
191 |
192 | DEPENDENCIES
193 | annotate
194 | bcrypt (~> 3.1.7)
195 | byebug
196 | capybara (~> 2.13)
197 | coffee-rails (~> 4.2)
198 | faker
199 | jbuilder (~> 2.5)
200 | jquery-rails
201 | listen (>= 3.0.5, < 3.2)
202 | pg (~> 0.18)
203 | pry-rails
204 | puma (~> 3.7)
205 | rails (~> 5.1.3)
206 | sass-rails (~> 5.0)
207 | selenium-webdriver
208 | spring
209 | spring-watcher-listen (~> 2.0.0)
210 | tzinfo-data
211 | uglifier (>= 1.3.0)
212 | web-console (>= 3.3.0)
213 |
214 | BUNDLED WITH
215 | 1.14.6
216 |
--------------------------------------------------------------------------------