Compare commits
3 Commits
65ce9c0716
...
01c0ab9cc0
Author | SHA1 | Date |
---|---|---|
Trevor Vallender | 01c0ab9cc0 | |
Trevor Vallender | 46d8a4bbca | |
Trevor Vallender | b58c0a7c1a |
2
Gemfile
2
Gemfile
|
@ -15,7 +15,7 @@ gem "jbuilder"
|
||||||
gem "bcrypt", "~> 3.1.7"
|
gem "bcrypt", "~> 3.1.7"
|
||||||
gem "tzinfo-data", platforms: %i[ windows jruby ]
|
gem "tzinfo-data", platforms: %i[ windows jruby ]
|
||||||
gem "bootsnap", require: false
|
gem "bootsnap", require: false
|
||||||
# gem "image_processing", "~> 1.2"
|
gem "image_processing", "~> 1.2"
|
||||||
|
|
||||||
gem "solid_queue"
|
gem "solid_queue"
|
||||||
gem "mission_control-jobs"
|
gem "mission_control-jobs"
|
||||||
|
|
|
@ -105,6 +105,7 @@ GEM
|
||||||
erubi (1.12.0)
|
erubi (1.12.0)
|
||||||
et-orbi (1.2.11)
|
et-orbi (1.2.11)
|
||||||
tzinfo
|
tzinfo
|
||||||
|
ffi (1.16.3)
|
||||||
fugit (1.10.1)
|
fugit (1.10.1)
|
||||||
et-orbi (~> 1, >= 1.2.7)
|
et-orbi (~> 1, >= 1.2.7)
|
||||||
raabro (~> 1.4)
|
raabro (~> 1.4)
|
||||||
|
@ -112,6 +113,9 @@ GEM
|
||||||
activesupport (>= 6.1)
|
activesupport (>= 6.1)
|
||||||
i18n (1.14.5)
|
i18n (1.14.5)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
|
image_processing (1.12.2)
|
||||||
|
mini_magick (>= 4.9.5, < 5)
|
||||||
|
ruby-vips (>= 2.0.17, < 3)
|
||||||
importmap-rails (2.0.1)
|
importmap-rails (2.0.1)
|
||||||
actionpack (>= 6.0.0)
|
actionpack (>= 6.0.0)
|
||||||
activesupport (>= 6.0.0)
|
activesupport (>= 6.0.0)
|
||||||
|
@ -135,6 +139,7 @@ GEM
|
||||||
net-smtp
|
net-smtp
|
||||||
marcel (1.0.4)
|
marcel (1.0.4)
|
||||||
matrix (0.4.2)
|
matrix (0.4.2)
|
||||||
|
mini_magick (4.12.0)
|
||||||
mini_mime (1.1.5)
|
mini_mime (1.1.5)
|
||||||
minitest (5.23.1)
|
minitest (5.23.1)
|
||||||
mission_control-jobs (0.2.1)
|
mission_control-jobs (0.2.1)
|
||||||
|
@ -259,6 +264,8 @@ GEM
|
||||||
rubocop-performance
|
rubocop-performance
|
||||||
rubocop-rails
|
rubocop-rails
|
||||||
ruby-progressbar (1.13.0)
|
ruby-progressbar (1.13.0)
|
||||||
|
ruby-vips (2.2.1)
|
||||||
|
ffi (~> 1.12)
|
||||||
rubyzip (2.3.2)
|
rubyzip (2.3.2)
|
||||||
selenium-webdriver (4.21.1)
|
selenium-webdriver (4.21.1)
|
||||||
base64 (~> 0.2)
|
base64 (~> 0.2)
|
||||||
|
@ -311,6 +318,7 @@ DEPENDENCIES
|
||||||
bootsnap
|
bootsnap
|
||||||
capybara
|
capybara
|
||||||
debug
|
debug
|
||||||
|
image_processing (~> 1.2)
|
||||||
importmap-rails
|
importmap-rails
|
||||||
jbuilder
|
jbuilder
|
||||||
mission_control-jobs
|
mission_control-jobs
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
|
||||||
|
* the trix-editor content (whether displayed or under editing). Feel free to incorporate this
|
||||||
|
* inclusion directly in any other asset bundle and remove this file.
|
||||||
|
*
|
||||||
|
*= require trix
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to override trix.css’s image gallery styles to accommodate the
|
||||||
|
* <action-text-attachment> element we wrap around attachments. Otherwise,
|
||||||
|
* images in galleries will be squished by the max-width: 33%; rule.
|
||||||
|
*/
|
||||||
|
.trix-content .attachment-gallery > action-text-attachment,
|
||||||
|
.trix-content .attachment-gallery > .attachment {
|
||||||
|
flex: 1 0 33%;
|
||||||
|
padding: 0 0.5em;
|
||||||
|
max-width: 33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trix-content .attachment-gallery.attachment-gallery--2 > action-text-attachment,
|
||||||
|
.trix-content .attachment-gallery.attachment-gallery--2 > .attachment, .trix-content .attachment-gallery.attachment-gallery--4 > action-text-attachment,
|
||||||
|
.trix-content .attachment-gallery.attachment-gallery--4 > .attachment {
|
||||||
|
flex-basis: 50%;
|
||||||
|
max-width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trix-content action-text-attachment .attachment {
|
||||||
|
padding: 0 !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
|
@ -12,4 +12,5 @@
|
||||||
--notice-text-color: #fff;
|
--notice-text-color: #fff;
|
||||||
|
|
||||||
--invalid-alert: #d00;
|
--invalid-alert: #d00;
|
||||||
|
--input-background: #fff;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
form {
|
form, fieldset {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
grid-template-columns: 1fr 2fr;
|
grid-template-columns: 1fr 2fr;
|
||||||
|
@ -31,4 +31,12 @@ form {
|
||||||
color: var(--invalid-alert);
|
color: var(--invalid-alert);
|
||||||
font-size: .8em;
|
font-size: .8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fieldset, p, trix-editor {
|
||||||
|
grid-column: 1/3;
|
||||||
|
}
|
||||||
|
|
||||||
|
trix-editor {
|
||||||
|
background-color: var(--input-background);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
|
|
||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
skip_before_action :authenticate, only: [ :new, :create ]
|
skip_before_action :authenticate, only: [ :new, :create ]
|
||||||
before_action :set_user, only: [ :show ]
|
before_action :set_user, only: [ :show, :edit, :update ]
|
||||||
|
before_action :ensure_self, only: [ :edit, :update ]
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@user = User.new
|
@user = User.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@user = User.new(user_params)
|
@user = User.new(new_user_params)
|
||||||
if @user.save
|
if @user.save
|
||||||
token = @user.generate_token_for(:email_verification)
|
token = @user.generate_token_for(:email_verification)
|
||||||
UserMailer.with(user: @user, token: token).email_verification.deliver_later
|
UserMailer.with(user: @user, token: token).email_verification.deliver_later
|
||||||
|
@ -27,9 +28,21 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @user.update(existing_user_params)
|
||||||
|
redirect_to @user, notice: t(".success")
|
||||||
|
else
|
||||||
|
flash.now[:alert] = t(".error")
|
||||||
|
render :edit, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def user_params
|
def new_user_params
|
||||||
params.require(:user).permit(
|
params.require(:user).permit(
|
||||||
:username,
|
:username,
|
||||||
:password,
|
:password,
|
||||||
|
@ -40,7 +53,22 @@ class UsersController < ApplicationController
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def existing_user_params
|
||||||
|
params.require(:user).permit(
|
||||||
|
:password,
|
||||||
|
:password_confirmation,
|
||||||
|
:password_challenge,
|
||||||
|
:first_name,
|
||||||
|
:last_name,
|
||||||
|
:profile,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def set_user
|
def set_user
|
||||||
@user = User.find_by(username: params[:id])
|
@user = User.find_by(username: params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ensure_self
|
||||||
|
head :forbidden unless @user == Current.user || Current.user.admin?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
|
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
|
||||||
import "@hotwired/turbo-rails"
|
import "@hotwired/turbo-rails"
|
||||||
import "controllers"
|
import "controllers"
|
||||||
|
|
||||||
|
import "trix"
|
||||||
|
import "@rails/actiontext"
|
||||||
|
|
|
@ -5,6 +5,7 @@ class User < ApplicationRecord
|
||||||
has_many :owned_tables, foreign_key: :owner_id, class_name: "Table"
|
has_many :owned_tables, foreign_key: :owner_id, class_name: "Table"
|
||||||
has_many :players, dependent: :destroy
|
has_many :players, dependent: :destroy
|
||||||
has_many :tables, through: :players
|
has_many :tables, through: :players
|
||||||
|
has_rich_text :profile
|
||||||
|
|
||||||
has_secure_password
|
has_secure_password
|
||||||
generates_token_for :password_reset, expires_in: 4.hours do
|
generates_token_for :password_reset, expires_in: 4.hours do
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
|
||||||
|
<% if blob.representable? %>
|
||||||
|
<%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<figcaption class="attachment__caption">
|
||||||
|
<% if caption = blob.try(:caption) %>
|
||||||
|
<%= caption %>
|
||||||
|
<% else %>
|
||||||
|
<span class="attachment__name"><%= blob.filename %></span>
|
||||||
|
<span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
|
||||||
|
<% end %>
|
||||||
|
</figcaption>
|
||||||
|
</figure>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<div class="trix-content">
|
||||||
|
<%= yield -%>
|
||||||
|
</div>
|
|
@ -19,6 +19,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<% if logged_in? %>
|
<% if logged_in? %>
|
||||||
<li><%= link_to t(".tables"), tables_path %></li>
|
<li><%= link_to t(".tables"), tables_path %></li>
|
||||||
|
<li><%= link_to t(".profile"), user_path(Current.user) %></li>
|
||||||
<li><%= link_to t("log_out"), logout_path, data: {turbo_method: :delete} %></li>
|
<li><%= link_to t("log_out"), logout_path, data: {turbo_method: :delete} %></li>
|
||||||
<% if Current.user.admin? %>
|
<% if Current.user.admin? %>
|
||||||
<li><%= link_to t("administration"), admin_index_path %></li>
|
<li><%= link_to t("administration"), admin_index_path %></li>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<section class="inset">
|
<section class="inset">
|
||||||
<%= form_with model: user do |f| %>
|
<%= form_with model: user do |f| %>
|
||||||
<%= f.label :username %>
|
<%= f.label :username %>
|
||||||
<%= f.text_field :username, required: true %>
|
<%= f.text_field :username, required: true, disabled: user.persisted? %>
|
||||||
<%= display_form_errors(user, :username) %>
|
<%= display_form_errors(user, :username) %>
|
||||||
|
|
||||||
<%= f.label :first_name %>
|
<%= f.label :first_name %>
|
||||||
|
@ -15,16 +15,34 @@
|
||||||
<%= display_form_errors(user, :last_name) %>
|
<%= display_form_errors(user, :last_name) %>
|
||||||
|
|
||||||
<%= f.label :email %>
|
<%= f.label :email %>
|
||||||
<%= f.text_field :email, required: true %>
|
<%= f.text_field :email, required: true, disabled: user.persisted? %>
|
||||||
<%= display_form_errors(user, :email) %>
|
<%= display_form_errors(user, :email) %>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend><%= t(".password") %></legend>
|
||||||
|
|
||||||
|
<% if user.persisted? %>
|
||||||
|
<%= f.label :password_challenge, t(".current_password") %>
|
||||||
|
<%= f.password_field :password_challenge, required: user.new_record? %>
|
||||||
|
<%= display_form_errors(user, :password_challenge) %>
|
||||||
|
|
||||||
|
<p><%= t(".password_hint") %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<%= f.label :password %>
|
<%= f.label :password %>
|
||||||
<%= f.password_field :password, required: true %>
|
<%= f.password_field :password, required: user.new_record? %>
|
||||||
<%= display_form_errors(user, :password) %>
|
<%= display_form_errors(user, :password) %>
|
||||||
|
|
||||||
<%= f.label :password_confirmation %>
|
<%= f.label :password_confirmation %>
|
||||||
<%= f.password_field :password_confirmation, required: true %>
|
<%= f.password_field :password_confirmation, required: user.new_record? %>
|
||||||
<%= display_form_errors(user, :password_confirmation) %>
|
<%= display_form_errors(user, :password_confirmation) %>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<% if user.persisted? %>
|
||||||
|
<%= f.label :profile %>
|
||||||
|
<%= f.rich_text_area :profile %>
|
||||||
|
<%= display_form_errors(user, :profile) %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<%= f.submit button_text %>
|
<%= f.submit button_text %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<% content_for :title, t(".edit_profile") %>
|
||||||
|
|
||||||
|
<h2><%= t(".edit_profile") %></h2>
|
||||||
|
|
||||||
|
<%= render partial: "users/form",
|
||||||
|
locals: { user: @user, button_text: t(".update_profile") } %>
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
<h2><%= @user.username %></h2>
|
<h2><%= @user.username %></h2>
|
||||||
|
|
||||||
<% if @user == Current.user && @table_invites.any? %>
|
<aside>
|
||||||
|
<% if @user == Current.user %>
|
||||||
|
<%= link_to t(".edit_profile"), edit_user_path(@user) %>
|
||||||
|
<% if @table_invites.any? %>
|
||||||
<%= link_to t(".your_invites"), table_invites_path %>
|
<%= link_to t(".your_invites"), table_invites_path %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<%= @user.profile %>
|
||||||
|
|
|
@ -7,3 +7,5 @@ pin "@hotwired/turbo-rails", to: "turbo.min.js"
|
||||||
pin "@hotwired/stimulus", to: "stimulus.min.js"
|
pin "@hotwired/stimulus", to: "stimulus.min.js"
|
||||||
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
|
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
|
||||||
pin_all_from "app/javascript/controllers", under: "controllers"
|
pin_all_from "app/javascript/controllers", under: "controllers"
|
||||||
|
pin "trix"
|
||||||
|
pin "@rails/actiontext", to: "actiontext.esm.js"
|
||||||
|
|
|
@ -15,6 +15,7 @@ en:
|
||||||
game_systems: Game Systems
|
game_systems: Game Systems
|
||||||
jobs: Jobs
|
jobs: Jobs
|
||||||
application:
|
application:
|
||||||
|
profile: Profile
|
||||||
tables: Tables
|
tables: Tables
|
||||||
mailer:
|
mailer:
|
||||||
greeting: "Hi %{name},"
|
greeting: "Hi %{name},"
|
||||||
|
@ -130,6 +131,17 @@ en:
|
||||||
success: "Thanks for joining Tabletop Companion, %{name}! Please check your email to verify your address."
|
success: "Thanks for joining Tabletop Companion, %{name}! Please check your email to verify your address."
|
||||||
show:
|
show:
|
||||||
your_invites: Your invites
|
your_invites: Your invites
|
||||||
|
edit_profile: Edit profile
|
||||||
|
edit:
|
||||||
|
edit_profile: Edit profile
|
||||||
|
update_profile: Update profile
|
||||||
|
form:
|
||||||
|
password: Password
|
||||||
|
password_hint: To keep your existing password, leave the below fields blank
|
||||||
|
current_password: Current password
|
||||||
|
update:
|
||||||
|
success: Your profile has been updated
|
||||||
|
error: Failed to update profile
|
||||||
user_mailer:
|
user_mailer:
|
||||||
email_verified:
|
email_verified:
|
||||||
content: |-
|
content: |-
|
||||||
|
|
|
@ -8,7 +8,7 @@ Rails.application.routes.draw do
|
||||||
get "login" => "sessions#new", as: :login
|
get "login" => "sessions#new", as: :login
|
||||||
delete "logout" => "sessions#destroy", as: :logout
|
delete "logout" => "sessions#destroy", as: :logout
|
||||||
|
|
||||||
resources :users, only: [ :new, :create, :show ]
|
resources :users, only: [ :new, :create, :show, :edit, :update ]
|
||||||
resources :account_verifications, only: [ :show ]
|
resources :account_verifications, only: [ :show ]
|
||||||
resources :sessions, only: [ :new, :create, :destroy ]
|
resources :sessions, only: [ :new, :create, :destroy ]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# This migration comes from active_storage (originally 20170806125915)
|
||||||
|
class CreateActiveStorageTables < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
# Use Active Record's configured type for primary and foreign keys
|
||||||
|
primary_key_type, foreign_key_type = primary_and_foreign_key_types
|
||||||
|
|
||||||
|
create_table :active_storage_blobs, id: primary_key_type do |t|
|
||||||
|
t.string :key, null: false
|
||||||
|
t.string :filename, null: false
|
||||||
|
t.string :content_type
|
||||||
|
t.text :metadata
|
||||||
|
t.string :service_name, null: false
|
||||||
|
t.bigint :byte_size, null: false
|
||||||
|
t.string :checksum
|
||||||
|
|
||||||
|
if connection.supports_datetime_with_precision?
|
||||||
|
t.datetime :created_at, precision: 6, null: false
|
||||||
|
else
|
||||||
|
t.datetime :created_at, null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
t.index [ :key ], unique: true
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table :active_storage_attachments, id: primary_key_type do |t|
|
||||||
|
t.string :name, null: false
|
||||||
|
t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
|
||||||
|
t.references :blob, null: false, type: foreign_key_type
|
||||||
|
|
||||||
|
if connection.supports_datetime_with_precision?
|
||||||
|
t.datetime :created_at, precision: 6, null: false
|
||||||
|
else
|
||||||
|
t.datetime :created_at, null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true
|
||||||
|
t.foreign_key :active_storage_blobs, column: :blob_id
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table :active_storage_variant_records, id: primary_key_type do |t|
|
||||||
|
t.belongs_to :blob, null: false, index: false, type: foreign_key_type
|
||||||
|
t.string :variation_digest, null: false
|
||||||
|
|
||||||
|
t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true
|
||||||
|
t.foreign_key :active_storage_blobs, column: :blob_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def primary_and_foreign_key_types
|
||||||
|
config = Rails.configuration.generators
|
||||||
|
setting = config.options[config.orm][:primary_key_type]
|
||||||
|
primary_key_type = setting || :primary_key
|
||||||
|
foreign_key_type = setting || :bigint
|
||||||
|
[ primary_key_type, foreign_key_type ]
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,28 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# This migration comes from action_text (originally 20180528164100)
|
||||||
|
class CreateActionTextTables < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
# Use Active Record's configured type for primary and foreign keys
|
||||||
|
primary_key_type, foreign_key_type = primary_and_foreign_key_types
|
||||||
|
|
||||||
|
create_table :action_text_rich_texts, id: primary_key_type do |t|
|
||||||
|
t.string :name, null: false
|
||||||
|
t.text :body, size: :long
|
||||||
|
t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
|
||||||
|
t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def primary_and_foreign_key_types
|
||||||
|
config = Rails.configuration.generators
|
||||||
|
setting = config.options[config.orm][:primary_key_type]
|
||||||
|
primary_key_type = setting || :primary_key
|
||||||
|
foreign_key_type = setting || :bigint
|
||||||
|
[ primary_key_type, foreign_key_type ]
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,10 +10,48 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.1].define(version: 2024_05_30_071707) do
|
ActiveRecord::Schema[7.1].define(version: 2024_05_30_073852) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
|
create_table "action_text_rich_texts", force: :cascade do |t|
|
||||||
|
t.string "name", null: false
|
||||||
|
t.text "body"
|
||||||
|
t.string "record_type", null: false
|
||||||
|
t.bigint "record_id", null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "active_storage_attachments", force: :cascade do |t|
|
||||||
|
t.string "name", null: false
|
||||||
|
t.string "record_type", null: false
|
||||||
|
t.bigint "record_id", null: false
|
||||||
|
t.bigint "blob_id", null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
|
||||||
|
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "active_storage_blobs", force: :cascade do |t|
|
||||||
|
t.string "key", null: false
|
||||||
|
t.string "filename", null: false
|
||||||
|
t.string "content_type"
|
||||||
|
t.text "metadata"
|
||||||
|
t.string "service_name", null: false
|
||||||
|
t.bigint "byte_size", null: false
|
||||||
|
t.string "checksum"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "active_storage_variant_records", force: :cascade do |t|
|
||||||
|
t.bigint "blob_id", null: false
|
||||||
|
t.string "variation_digest", null: false
|
||||||
|
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
|
||||||
|
end
|
||||||
|
|
||||||
create_table "game_systems", force: :cascade do |t|
|
create_table "game_systems", force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
|
@ -191,6 +229,8 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_30_071707) do
|
||||||
t.check_constraint "length(username::text) >= 3", name: "chk_username_min_length"
|
t.check_constraint "length(username::text) >= 3", name: "chk_username_min_length"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||||
|
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||||
add_foreign_key "players", "tables"
|
add_foreign_key "players", "tables"
|
||||||
add_foreign_key "players", "users"
|
add_foreign_key "players", "users"
|
||||||
add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
|
||||||
|
|
|
@ -34,6 +34,24 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_response :unprocessable_entity
|
assert_response :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "should get edit" do
|
||||||
|
sign_in users(:trevor)
|
||||||
|
get edit_user_url(users(:trevor))
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
|
test "can only edit own user" do
|
||||||
|
sign_in users(:trevor)
|
||||||
|
get edit_user_url(users(:gimli))
|
||||||
|
assert_response :forbidden
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should update user" do
|
||||||
|
sign_in users(:trevor)
|
||||||
|
patch user_url(users(:trevor)), params: { user: { profile: "All about me" } }
|
||||||
|
assert_redirected_to user_path(users(:trevor))
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def user_params
|
def user_params
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
one:
|
||||||
|
record: trevor (User)
|
||||||
|
name: profile
|
||||||
|
body: <p>I am just <strong>so awesome</strong></p>
|
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Preview all emails at http://localhost:3000/rails/mailers/table_invite_mailer
|
||||||
|
class TableInviteMailerPreview < ActionMailer::Preview
|
||||||
|
def invite_user
|
||||||
|
TableInviteMailer.with(table_invite: TableInvite.first).invite_user
|
||||||
|
end
|
||||||
|
|
||||||
|
def invite_new_user
|
||||||
|
TableInviteMailer.with(table_invite: TableInvite.first).invite_new_user
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue