Skip to content

Add display author to public content forms#1557

Open
maebeale wants to merge 1 commit into
mainfrom
maebeale/add-author-to-forms
Open

Add display author to public content forms#1557
maebeale wants to merge 1 commit into
mainfrom
maebeale/add-author-to-forms

Conversation

@maebeale
Copy link
Copy Markdown
Collaborator

@maebeale maebeale commented Jun 5, 2026

What is the goal of this PR and why is this important?

  • Public-facing stories, events, resources, and tutorials need a byline that can be attributed to a chosen author, independently of who actually created the record in the Portal.
  • Previously the displayed author was tied to created_by, so the public byline could not differ from the internal creator. This adds a dedicated "Display author" so editors control attribution directly.

How did you approach the change?

  • Added a nullable author reference (→ users) to stories, events, resources, and tutorials, plus a created_by reference to tutorials (it previously had none).
  • Added belongs_to :author, class_name: "User", optional: true to each model.
  • Added a "Display author" select to each public form, defaulting to the existing author/creator or the current user.
  • Switched Story search and the author sort column to use the new author association instead of created_by.
  • Permitted author_id (and created_by_id where needed) in the controllers and updated factories.

UI Testing Checklist

  • Story form: "Display author" select appears, saves, and drives the displayed byline
  • Event form: "Display author" select appears and saves; "Created by" still shown
  • Resource form: "Display author" select appears and saves
  • Tutorial form: "Display author" select appears and saves; created_by set on create
  • Stories index: author column sort works against the new association

Anything else to add?

  • The branch is based on a commit ~127 behind main; the PR diff is clean (only the author changes) since the base is a direct ancestor, but a rebase before merge may be worth it. Screenshots to be added for the four forms.

Content editors need to attribute public-facing stories, events, resources,
and tutorials to a chosen author independently of who created the record, so
the displayed byline can differ from the internal creator.

- Add nullable author reference (User) to stories, events, resources, tutorials
- Add created_by reference to tutorials so it can track its internal creator
- Add a "Display author" select to each public form, defaulting to the
  existing author/creator or the current user
- Switch Story search and author sort to use the new author association
- Permit author_id params and update factories

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 5, 2026 13:41
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a dedicated “Display author” for public-facing content (stories, events, resources, tutorials) so public attribution can differ from the internal creator (created_by). It adds new author associations, wires them into the admin forms/controllers, and updates story search/sorting to use the new association.

Changes:

  • Added author references to stories/events/resources/tutorials and a new created_by reference for tutorials.
  • Added belongs_to :author (and tutorial :created_by) associations and updated Story search/sort joins to use author.
  • Added “Display author” selects to the relevant forms and permitted author_id in controllers (plus supporting factory updates).

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
spec/factories/tutorials.rb Adds author/created_by associations to tutorial factory.
spec/factories/stories.rb Adds author association to story factory.
spec/factories/resources.rb Adds author association to resource factory.
spec/factories/events.rb Adds author association to event factory.
db/migrate/20260308143000_add_author_to_public_forms.rb Adds author_id refs to public models and created_by_id to tutorials.
app/views/tutorials/_form.html.erb Adds display-author select and a created_by_id hidden field.
app/views/stories/_form.html.erb Adds display-author select to story form.
app/views/resources/_form.html.erb Adds display-author select to resource form.
app/views/events/_form.html.erb Adds display-author select and adjusts “Created by” display placement.
app/models/tutorial.rb Adds author and created_by associations.
app/models/story.rb Adds author association and switches search join to author.
app/models/resource.rb Adds author association (note: collides with existing author string column).
app/models/event.rb Adds author association.
app/controllers/tutorials_controller.rb Sets created_by on create, builds authors list, permits author_id/created_by_id.
app/controllers/stories_controller.rb Includes author in index scope, builds authors list, sorts/permits author_id.
app/controllers/resources_controller.rb Builds authors list using author_id and permits author_id.
app/controllers/events_controller.rb Builds authors list and permits author_id.

Comment thread app/models/resource.rb
Comment on lines +17 to 18
belongs_to :author, class_name: "User", optional: true
belongs_to :created_by, class_name: "User"
@resource.gallery_assets.build
@windows_types = WindowsType.all
@authors = authorized_scope(User.has_access.or(User.where(id: @resource.created_by_id)))
@authors = authorized_scope(User.has_access.or(User.where(id: @resource.author_id)))
Comment on lines +415 to +420
<%= f.input :author_id,
as: :select,
label: "Display author",
collection: @authors,
selected: f.object.author_id || current_user&.id,
input_html: { class: "block w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm" } %>
Comment on lines +265 to +270
<%= f.input :author_id,
as: :select,
label: "Display author",
collection: @authors,
selected: f.object.author_id || current_user&.id,
input_html: { class: "block w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm" } %>
Comment on lines +33 to +38
<%= f.input :author_id,
as: :select,
label: "Display author",
collection: @authors,
selected: f.object.author_id || current_user&.id,
input_html: { class: "block w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm" } %>
Comment on lines 124 to 128
def tutorial_params
params.require(:tutorial).permit(
:title, :body, :rhino_body, :position, :youtube_url,
:author_id, :created_by_id,
:featured, :published, :publicly_visible, :publicly_featured,
@@ -1,4 +1,5 @@
<%= simple_form_for(@tutorial, html: { multipart: true }) do |f| %>
<%= f.hidden_field :created_by_id, value: f.object.created_by_id || current_user&.id %>
.order(:created_at)
@people = Person.order(Arel.sql("LOWER(first_name), LOWER(last_name)"))
@users = User.has_access.includes(:person).left_joins(:person).order(Arel.sql("people.first_name IS NULL, LOWER(people.first_name), LOWER(people.last_name), LOWER(users.email)"))
@authors = authorized_scope(User.has_access.or(User.where(id: @story.author_id)))
.select { |type, _| type.nil? || (type.published? && !type.story_specific? && !type.profile_specific?) }
.sort_by { |type, _| type&.name.to_s.downcase }
@sectors = Sector.published.order(:name)
@authors = authorized_scope(User.has_access.or(User.where(id: @event.author_id)))
.select { |type, _| type.nil? || type.published? }
.sort_by { |type, _| type&.name.to_s.downcase }
@sectors = Sector.published.order(:name)
@authors = authorized_scope(User.has_access.or(User.where(id: @tutorial.author_id)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants