Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project aliases #2644

Draft
wants to merge 40 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c94f5e2
Generate model ProjectAlias
mo-nathan Dec 26, 2024
b8f3756
Rubocop
mo-nathan Dec 26, 2024
3ac26fb
Hookup ProjectAlias class
mo-nathan Dec 26, 2024
2229d1c
Fix migration to use integers for references
mo-nathan Dec 26, 2024
12c738d
Rubocop
mo-nathan Dec 26, 2024
5aac91a
Merge branch 'main' into njw-project-aliases
mo-nathan Dec 29, 2024
fd9e403
Some simple tests
mo-nathan Dec 29, 2024
744d015
Merge branch 'main' into njw-project-aliases
mo-nathan Dec 31, 2024
f5e79bb
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 5, 2025
2ebaf43
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 7, 2025
ec1e816
First pass at CRUD
mo-nathan Jan 10, 2025
829ea96
Rejigger ProjectAliases
mo-nathan Jan 11, 2025
6fe4e88
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 11, 2025
a1ce799
Rubocop
mo-nathan Jan 11, 2025
8482da1
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 12, 2025
33946f2
Project Alias improvements
mo-nathan Jan 13, 2025
bd5baf9
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 14, 2025
24233b7
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 14, 2025
fb4e4b7
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 15, 2025
2ad9e33
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 16, 2025
ab0ccf8
Get autocompleter to switch from location to user
mo-nathan Jan 17, 2025
16236da
Autocomplete fixes
mo-nathan Jan 17, 2025
441c144
Fix new action for ProjectAliases
mo-nathan Jan 18, 2025
9493462
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 18, 2025
35a2c25
Project Alias form fixes
mo-nathan Jan 18, 2025
339eb57
Add more parens
mo-nathan Jan 18, 2025
ea2d105
Fixes for Project Alias delete routes
mo-nathan Jan 18, 2025
12a46ed
Add tests for Project Alias controller
mo-nathan Jan 18, 2025
edecd37
Rubocop
mo-nathan Jan 18, 2025
bdb6a9e
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 19, 2025
d8f0ba4
PR feedback
mo-nathan Jan 19, 2025
e6ed733
Switch to underscore test names
mo-nathan Jan 19, 2025
ebd42a5
Switch to submit button and cleanup button name
mo-nathan Jan 19, 2025
15d7e37
Add links to targets and remove show link
mo-nathan Jan 19, 2025
e63b77e
Add alias lookup when saving a field slip form
mo-nathan Jan 19, 2025
aff4fd3
Fix broken tests
mo-nathan Jan 22, 2025
cd9ad1b
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 22, 2025
120b5c2
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 23, 2025
d9fd3a0
Update user_str based on new interface for lookup_unique_text_name
mo-nathan Jan 23, 2025
8ed460f
Merge branch 'main' into njw-project-aliases
mo-nathan Jan 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions app/controllers/projects/aliases_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# frozen_string_literal: true

module Projects
class AliasesController < ApplicationController
before_action :login_required
before_action :pass_query_params, except: [:index]
before_action :set_project_alias, only: [:show, :edit, :update, :destroy]

def index
@project = Project.find(params[:project_id])
@project_aliases = ProjectAlias.all
respond_to do |format|
format.html
format.json { render(json: @project_aliases) }
end
end

def show
respond_to do |format|
format.html
format.json { render(json: @project_alias) }
end
end

def new
@project_alias = ProjectAlias.new(project_id: params.require(:project_id))
end

def edit; end

def create
@project_alias = ProjectAlias.new(project_alias_params)

respond_to do |format|
if @project_alias.save
format.html do
redirect_to(@project_alias,
notice: :project_alias_created.t)
end
format.json do
render(json: @project_alias, status: :created,
location: @project_alias)
end
else
format.html { render(:new) }
format.json do
render(json: @project_alias.errors, status: :unprocessable_entity)
end
end
end
end

def update
respond_to do |format|
if @project_alias.update(project_alias_params)
format.html do
redirect_to(@project_alias,
notice: :project_alias_updated.t)
end
format.json { render(json: @project_alias) }
else
format.html { render(:edit) }
format.json do
render(json: @project_alias.errors, status: :unprocessable_entity)
end
end
end
end

def destroy
@project_alias.destroy
respond_to do |format|
format.html do
redirect_to(project_aliases_url,
notice: :project_alias_deleted.t)
end
format.json { head(:no_content) }
end
end

private

def set_project_alias
@project_alias = ProjectAlias.find(params[:id])
end

def project_alias_params
params.require(:project_alias).permit(:name, :project_id, :target_type,
:target_id)
end
end
end
1 change: 1 addition & 0 deletions app/models/location.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class Location < AbstractModel # rubocop:disable Metrics/ClassLength
has_many :interests, as: :target, dependent: :destroy, inverse_of: :target
has_many :observations
has_many :projects
has_many :project_aliases, as: :target, dependent: :destroy
has_many :species_lists
has_many :herbaria # should be at most one, but nothing preventing more
has_many :users # via profile location
Expand Down
2 changes: 2 additions & 0 deletions app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ class Project < AbstractModel # rubocop:disable Metrics/ClassLength
has_many :project_species_lists, dependent: :destroy
has_many :species_lists, through: :project_species_lists

has_many :project_aliases, dependent: :destroy

before_destroy :orphan_drafts
validates :field_slip_prefix, uniqueness: true, allow_blank: true
validates :field_slip_prefix,
Expand Down
8 changes: 8 additions & 0 deletions app/models/project_alias.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class ProjectAlias < ApplicationRecord
belongs_to :target, polymorphic: true
belongs_to :project

validates :name, presence: true
end
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ class User < AbstractModel # rubocop:disable Metrics/ClassLength
has_many :projects_created, class_name: "Project"
has_many :project_members, dependent: :destroy
has_many :projects, through: :project_members, source: :projects
has_many :project_aliases, as: :target, dependent: :destroy
has_many :publications
has_many :queued_emails
has_many :sequences
Expand Down
36 changes: 36 additions & 0 deletions app/views/controllers/projects/aliases/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<%= form_with(model: project_alias) do |form| %>
<% if project_alias.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(project_alias.errors.count, "error") %> prohibited this project alias from being saved:</h2>
<ul>
<% project_alias.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>

<div class="field">
<%= form.label(:name) %>
<%= form.text_field(:name) %>
</div>

<div class="field">
<%= form.label(:project_id) %>
<%= form.collection_select(:project_id, Project.all, :id, :title) %>
</div>

<div class="field">
<%= form.label(:target_type) %>
<%= form.select(:target_type, ['Location', 'User']) %>
</div>

<div class="field">
<%= form.label(:target_id) %>
<%= form.number_field(:target_id) %>
</div>

<div class="actions">
<%= form.submit %>
</div>
mo-nathan marked this conversation as resolved.
Show resolved Hide resolved
<% end %>
9 changes: 9 additions & 0 deletions app/views/controllers/projects/aliases/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<h1>Editing Project Alias</h1>

<%= render('form', project_alias: @project_alias) %>

<%
project_id = @project_alias.project_id
%>
<%= link_to 'Show', project_alias_path(project_id:, id: @project_alias.id) %> |
<%= link_to 'Back', project_aliases_path(project_id:) %>
39 changes: 39 additions & 0 deletions app/views/controllers/projects/aliases/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<%
add_project_banner(@project)

@container = :wide

project_id = @project.id
action = { controller: "/projects/project_aliases", action: :create,
project_id: @project.id, q: get_query_param }
%>

<h1>Project Aliases</h1>

<table class="table table-striped table-project-members mt-3">
<thead>
<tr>
<th>Name</th>
<th>Target Type</th>
<th>Target</th>
<th>Actions</th>
</tr>
</thead>

<tbody>
<% @project_aliases.each do |project_alias| %>
<tr>
<td><%= project_alias.name %></td>
<td><%= project_alias.target_type %></td>
<td><%= project_alias.target.try(:name) %></td>
<td>
<%= link_to 'Show', project_alias_path(project_id:, id: project_alias.id) %>
<%= link_to 'Edit', edit_project_alias_path(project_id:, id: project_alias.id) %>
<%= link_to 'Delete', project_alias_path(project_id:, id: project_alias.id), method: :delete, data: { confirm: 'Are you sure?' } %>
</td>
</tr>
<% end %>
</tbody>
</table>

<%= link_to 'New Project Alias', new_project_alias_path(project_id:) %>
5 changes: 5 additions & 0 deletions app/views/controllers/projects/aliases/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<h1>New Project Alias</h1>

<%= render('form', project_alias: @project_alias) %>

<%= link_to('Back', project_aliases_path(project_id: @project_alias.project_id)) %>
17 changes: 17 additions & 0 deletions app/views/controllers/projects/aliases/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<p>
<strong>Name:</strong>
<%= @project_alias.name %>
</p>

<p>
<strong>Target Type:</strong>
<%= @project_alias.target_type %>
</p>

<p>
<strong>Target:</strong>
<%= @project_alias.target.try(:name) %>
</p>

<%= link_to 'Edit', edit_project_alias_path(prjoect_id: @project_alias.project_id, id: @project_alias.id) %> |
<%= link_to 'Back', project_aliases_path %>
5 changes: 5 additions & 0 deletions config/locales/en.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2893,6 +2893,11 @@
field_slips_too_many_field_slips: You have requested more than [MAX] slips.
field_slips_one_per_page: One field slip per page. Print shops prefer this. Otherwise 6/page which works best on US letter page.

# Project Aliases
project_alias_created: Field slip was successfully created.
project_alias_destroyed: Field slip was successfully destroyed.
project_alias_updated: Field slip was successfully updated.

##############################################################################

# LESS POPULAR PAGES
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ def route_actions_hash
controller: "projects/locations"
resources :members, only: [:new, :create, :edit, :update, :index],
controller: "projects/members", param: :candidate
resources :aliases, controller: "projects/aliases"
resources :violations, only: [:index], controller: "projects/violations"
end
# resourceful route won't work because it requires an additional id
Expand Down
18 changes: 18 additions & 0 deletions db/migrate/20241226192904_create_project_aliases.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

class CreateProjectAliases < ActiveRecord::Migration[7.1]
def change
create_table(:project_aliases) do |t|
t.integer(:project_id, null: false)
t.integer(:target_id, null: false)
t.string(:target_type, null: false)
t.string(:name)

t.timestamps

t.foreign_key(:projects)
t.index([:target_type, :target_id])
t.index(:project_id)
end
end
end
14 changes: 13 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2024_12_09_041049) do
ActiveRecord::Schema[7.1].define(version: 2024_12_26_192904) do
create_table "api_keys", id: :integer, charset: "utf8mb3", force: :cascade do |t|
t.datetime "created_at", precision: nil
t.datetime "last_used", precision: nil
Expand Down Expand Up @@ -558,6 +558,17 @@
t.datetime "updated_at", null: false
end

create_table "project_aliases", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.integer "project_id", null: false
t.integer "target_id", null: false
t.string "target_type", null: false
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["project_id"], name: "index_project_aliases_on_project_id"
t.index ["target_type", "target_id"], name: "index_project_aliases_on_target_type_and_target_id"
end

create_table "project_images", charset: "utf8mb3", force: :cascade do |t|
t.integer "image_id", null: false
t.integer "project_id", null: false
Expand Down Expand Up @@ -965,6 +976,7 @@
t.index ["observation_id"], name: "observation_index"
end

add_foreign_key "project_aliases", "projects"
add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "solid_queue_claimed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
add_foreign_key "solid_queue_failed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
Expand Down
13 changes: 13 additions & 0 deletions test/fixtures/project_aliases.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
target: rolf
target_type: User
name: MyString
project: eol_project

two:
target: albion
target_type: Location
name: MyString
project: eol_project
16 changes: 16 additions & 0 deletions test/models/project_alias_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

require "test_helper"

class ProjectAliasTest < ActiveSupport::TestCase
test "valid user aliases" do
pa = Project.find_by(target_type: "User")
assert_equal("User", pa.target_type)
assert_equal(User, pa.target.class)
end

test "valid location aliases" do
pa = Project.find_by(target_type: "Location")
assert_equal(Location, pa.target.class)
mo-nathan marked this conversation as resolved.
Show resolved Hide resolved
end
end
Loading