From c583ee7f32ae815cc0106447f804a6c906ce5089 Mon Sep 17 00:00:00 2001 From: "Jesse C. Fisher" Date: Mon, 4 Dec 2023 08:27:21 +0000 Subject: [PATCH] Add Chat Rooms with Turbo --- Gemfile.lock | 3 + app/assets/javascripts/rooms.coffee | 3 + app/assets/stylesheets/rooms.scss | 3 + app/controllers/application_controller.rb | 4 +- app/controllers/rooms_controller.rb | 28 ++++++++++ app/helpers/rooms_helper.rb | 2 + app/javascript/application.js | 1 + app/models/room.rb | 5 ++ app/policies/room_policy.rb | 56 +++++++++++++++++++ app/views/layouts/_new_room_form.html.haml | 3 + app/views/rooms/_room.html.haml | 2 + app/views/rooms/index.html.haml | 11 ++++ config/cable.yml | 3 +- config/importmap.rb | 1 + .../devise_permitted_parameters.rb | 24 ++++---- config/routes.rb | 1 + db/migrate/20231203160243_create_rooms.rb | 10 ++++ db/schema.rb | 9 ++- spec/factories/rooms.rb | 6 ++ spec/helpers/rooms_helper_spec.rb | 15 +++++ spec/models/room_spec.rb | 5 ++ spec/requests/rooms_spec.rb | 11 ++++ spec/views/rooms/index.html.haml_spec.rb | 5 ++ 23 files changed, 195 insertions(+), 16 deletions(-) create mode 100644 app/assets/javascripts/rooms.coffee create mode 100644 app/assets/stylesheets/rooms.scss create mode 100644 app/controllers/rooms_controller.rb create mode 100644 app/helpers/rooms_helper.rb create mode 100644 app/models/room.rb create mode 100644 app/policies/room_policy.rb create mode 100644 app/views/layouts/_new_room_form.html.haml create mode 100644 app/views/rooms/_room.html.haml create mode 100644 app/views/rooms/index.html.haml create mode 100644 db/migrate/20231203160243_create_rooms.rb create mode 100644 spec/factories/rooms.rb create mode 100644 spec/helpers/rooms_helper_spec.rb create mode 100644 spec/models/room_spec.rb create mode 100644 spec/requests/rooms_spec.rb create mode 100644 spec/views/rooms/index.html.haml_spec.rb diff --git a/Gemfile.lock b/Gemfile.lock index 07759e3d..5d3a34fe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -352,6 +352,8 @@ GEM nokogiri (1.15.5) mini_portile2 (~> 2.8.2) racc (~> 1.4) + nokogiri (1.15.5-x86_64-linux) + racc (~> 1.4) notiffany (0.1.3) nenv (~> 0.1) shellany (~> 0.0) @@ -566,6 +568,7 @@ GEM PLATFORMS ruby + x86_64-linux DEPENDENCIES activejob-status (~> 1.0) diff --git a/app/assets/javascripts/rooms.coffee b/app/assets/javascripts/rooms.coffee new file mode 100644 index 00000000..24f83d18 --- /dev/null +++ b/app/assets/javascripts/rooms.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/rooms.scss b/app/assets/stylesheets/rooms.scss new file mode 100644 index 00000000..032a00ae --- /dev/null +++ b/app/assets/stylesheets/rooms.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Rooms controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: https://sass-lang.com/ diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1e3d44ca..d852018d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -19,8 +19,8 @@ class ApplicationController < ActionController::Base def user_not_authorized(exception) policy_name = exception.policy.class.to_s.underscore # flash[:alert] = "#{policy_name}.#{exception.query}" - # flash[:alert] = "Unable to #{exception.query[0..-2]} #{policy_name.split("_")[0].capitalize}" - flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default + # flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default + flash[:alert] = "Unable to #{exception.query[0..-2]} #{policy_name.split("_")[0].capitalize}" redirect_to (request.referrer || root_path) end end diff --git a/app/controllers/rooms_controller.rb b/app/controllers/rooms_controller.rb new file mode 100644 index 00000000..59e3acd4 --- /dev/null +++ b/app/controllers/rooms_controller.rb @@ -0,0 +1,28 @@ +class RoomsController < ApplicationController + before_action :set_room, only: %i[ show edit update destroy ] + def index + @rooms = policy_scope Room.all + authorize @rooms + authorize @new_room = Room.new + end + + def create + authorize @room = Room.build(name: params["room"]["name"]) + @room.save + end + + def show + authorize @room + @rooms = Room.public_rooms + + render "index" + end + + private + + # Use callbacks to share common setup or constraints between actions. + def set_room + @room = Room.find(params[:id]) + end + +end diff --git a/app/helpers/rooms_helper.rb b/app/helpers/rooms_helper.rb new file mode 100644 index 00000000..1d0f4c73 --- /dev/null +++ b/app/helpers/rooms_helper.rb @@ -0,0 +1,2 @@ +module RoomsHelper +end diff --git a/app/javascript/application.js b/app/javascript/application.js index fa490ba5..d91508c8 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1 +1,2 @@ import 'controllers' +import "@hotwired/turbo-rails" diff --git a/app/models/room.rb b/app/models/room.rb new file mode 100644 index 00000000..427c72ec --- /dev/null +++ b/app/models/room.rb @@ -0,0 +1,5 @@ +class Room < ActiveRecord::Base + validates_uniqueness_of :name + scope :public_rooms, -> {where(is_private: false)} + after_create_commit { broadcast_append_to "rooms" } +end diff --git a/app/policies/room_policy.rb b/app/policies/room_policy.rb new file mode 100644 index 00000000..576c4cc4 --- /dev/null +++ b/app/policies/room_policy.rb @@ -0,0 +1,56 @@ +class RoomPolicy + attr_reader :user, :model + + def initialize(user, model) + @user = user || User.new + @room = model + end + + class Scope + def initialize(user, scope) + @user = user + @scope = scope + end + + def resolve + if user.admin? + scope.all + else + #TODO: private chats + scope.all + end + end + + private + + attr_reader :user, :scope + end + + def index? + true + end + + def show? + true + end + + def new? + @user.admin? + end + + def create? + @user.admin? + end + + def edit? + @user.admin? + end + + def update? + @user.admin? + end + + def destroy? + @user.admin? + end +end diff --git a/app/views/layouts/_new_room_form.html.haml b/app/views/layouts/_new_room_form.html.haml new file mode 100644 index 00000000..29e25881 --- /dev/null +++ b/app/views/layouts/_new_room_form.html.haml @@ -0,0 +1,3 @@ += form_with(model: @new_room, remote: true) do |f| + = f.text_field :name, class: "form-control", autocomplete: 'off' + = f.submit data: { disable_with: false } diff --git a/app/views/rooms/_room.html.haml b/app/views/rooms/_room.html.haml new file mode 100644 index 00000000..9fb75e86 --- /dev/null +++ b/app/views/rooms/_room.html.haml @@ -0,0 +1,2 @@ +%div + = link_to room.name, room diff --git a/app/views/rooms/index.html.haml b/app/views/rooms/index.html.haml new file mode 100644 index 00000000..6c462390 --- /dev/null +++ b/app/views/rooms/index.html.haml @@ -0,0 +1,11 @@ +- if @room + %h4= @room.name + +%h1 Rooms index + += render partial: "layouts/new_room_form" + += turbo_stream_from "rooms" +#rooms + %div + = render @rooms diff --git a/config/cable.yml b/config/cable.yml index 0a5192af..8b4d0f3f 100644 --- a/config/cable.yml +++ b/config/cable.yml @@ -1,5 +1,6 @@ development: - adapter: async + adapter: redis + url: redis://127.0.0.1:6379/1 test: adapter: test diff --git a/config/importmap.rb b/config/importmap.rb index 4f58f60c..da7d9e3d 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -6,3 +6,4 @@ pin '@hotwired/stimulus-loading', to: 'stimulus-loading.js', preload: true pin_all_from 'app/javascript/models', under: 'models' pin_all_from 'app/javascript/controllers', under: 'controllers' pin_all_from 'app/javascript/subscriptions', under: 'subscriptions' +pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true diff --git a/config/initializers/devise_permitted_parameters.rb b/config/initializers/devise_permitted_parameters.rb index 1be016b6..ec662076 100644 --- a/config/initializers/devise_permitted_parameters.rb +++ b/config/initializers/devise_permitted_parameters.rb @@ -1,16 +1,16 @@ -module DevisePermittedParameters - extend ActiveSupport::Concern +# module DevisePermittedParameters +# extend ActiveSupport::Concern - included do - before_action :configure_permitted_parameters - end +# included do +# before_action :configure_permitted_parameters +# end - protected +# protected - def configure_permitted_parameters - devise_parameter_sanitizer.permit(:sign_up, keys: [:name]) - devise_parameter_sanitizer.permit(:account_update, keys: [:name]) - end -end +# def configure_permitted_parameters +# devise_parameter_sanitizer.permit(:sign_up, keys: [:name]) +# devise_parameter_sanitizer.permit(:account_update, keys: [:name]) +# end +# end -DeviseController.send :include, DevisePermittedParameters +# DeviseController.send :include, DevisePermittedParameters diff --git a/config/routes.rb b/config/routes.rb index f3a04027..0b843645 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :rooms resources :commands do member do get 'run' diff --git a/db/migrate/20231203160243_create_rooms.rb b/db/migrate/20231203160243_create_rooms.rb new file mode 100644 index 00000000..ce952f23 --- /dev/null +++ b/db/migrate/20231203160243_create_rooms.rb @@ -0,0 +1,10 @@ +class CreateRooms < ActiveRecord::Migration[6.1] + def change + create_table :rooms do |t| + t.string :name + t.boolean :is_private, default: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 3a09a8ee..9f3327d8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_12_02_164132) do +ActiveRecord::Schema.define(version: 2023_12_03_160243) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -179,6 +179,13 @@ ActiveRecord::Schema.define(version: 2023_12_02_164132) do t.index ["follower_id"], name: "index_relationships_on_follower_id" end + create_table "rooms", force: :cascade do |t| + t.string "name" + t.boolean "is_private", default: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + create_table "seats", force: :cascade do |t| t.integer "table_id" t.integer "user_id" diff --git a/spec/factories/rooms.rb b/spec/factories/rooms.rb new file mode 100644 index 00000000..cca23983 --- /dev/null +++ b/spec/factories/rooms.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :room do + name "MyString" + is_private false + end +end diff --git a/spec/helpers/rooms_helper_spec.rb b/spec/helpers/rooms_helper_spec.rb new file mode 100644 index 00000000..d7775a56 --- /dev/null +++ b/spec/helpers/rooms_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the RoomsHelper. For example: +# +# describe RoomsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe RoomsHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/room_spec.rb b/spec/models/room_spec.rb new file mode 100644 index 00000000..dc75c5e1 --- /dev/null +++ b/spec/models/room_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Room, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/rooms_spec.rb b/spec/requests/rooms_spec.rb new file mode 100644 index 00000000..e1d2d491 --- /dev/null +++ b/spec/requests/rooms_spec.rb @@ -0,0 +1,11 @@ +require 'rails_helper' + +RSpec.describe "Rooms", type: :request do + describe "GET /index" do + it "returns http success" do + get "/rooms/index" + expect(response).to have_http_status(:success) + end + end + +end diff --git a/spec/views/rooms/index.html.haml_spec.rb b/spec/views/rooms/index.html.haml_spec.rb new file mode 100644 index 00000000..5bab03e2 --- /dev/null +++ b/spec/views/rooms/index.html.haml_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe "rooms/index.html.haml", type: :view do + pending "add some examples to (or delete) #{__FILE__}" +end