Skip to content

Commit

Permalink
Merge pull request #233 from uclibs/162-fix-500-error-on-submission
Browse files Browse the repository at this point in the history
162 fix 500 error on submission
  • Loading branch information
hortongn authored Oct 11, 2023
2 parents 75a10cc + 37eccee commit 018057e
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 20 deletions.
4 changes: 0 additions & 4 deletions Capfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ require 'capistrano/rails/migrations'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

task :use_rvm do
require 'capistrano/rvm'
end

task :use_rbenv do
require 'capistrano/rbenv'
# require 'capistrano/rbenv_install'
Expand Down
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ group :development do
gem 'capistrano-rails', '~> 1.4', require: false
gem 'capistrano-rbenv', '~> 2.0' # required
gem 'capistrano-rbenv-install', '~> 1.2.0'
gem 'capistrano-rvm', require: false
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'listen', '>= 3.0.5', '< 3.9'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
Expand Down
4 changes: 0 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ GEM
capistrano-rbenv-install (1.2.0)
capistrano (>= 3.0)
capistrano-rbenv (>= 2.0)
capistrano-rvm (0.1.2)
capistrano (~> 3.0)
sshkit (~> 1.2)
capybara (3.39.2)
addressable
matrix
Expand Down Expand Up @@ -366,7 +363,6 @@ DEPENDENCIES
capistrano-rails (~> 1.4)
capistrano-rbenv (~> 2.0)
capistrano-rbenv-install (~> 1.2.0)
capistrano-rvm
capybara (>= 2.15)
capybara-selenium (~> 0.0.6)
coffee-rails (~> 5.0)
Expand Down
25 changes: 25 additions & 0 deletions app/controllers/publications_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# frozen_string_literal: true

# == Schema Information
#
# Controller: PublicationsController
#
# Overview:
# The PublicationsController handles the CRUD operations for various types of
# publications like Artwork, Book, BookChapter, and so on. It is designed to
# handle submissions from both admin and regular users.
#
# Responsibilities:
# - Filtering requests based on the logged-in user type (Admin or regular user)
# - Managing CRUD operations for multiple publication types
# - Sending notifications via PublicationMailer upon successful publication submission
# - Redirecting based on various conditions such as user session and max submissions
#
# Special Behaviors:
# - Utilizes dynamic setting of instance variables and object types
# - Makes extensive use of helpers for finding records
#
# Filters:
# - set_object: Sets the object based on the controller name and params[:id].
# - signed_in: Checks if the user is signed in before granting access to certain actions.
# - check_max_submissions: Checks if the maximum submission limit is reached for a given user.
#

class PublicationsController < ApplicationController
before_action :set_object, only: %i[show edit update destroy]
before_action :signed_in, only: %i[index show edit update destroy]
Expand Down
29 changes: 29 additions & 0 deletions app/helpers/mailer_helper.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,37 @@
# frozen_string_literal: true

# MailerHelper Module
# ====================
#
# The MailerHelper module provides utility methods to assist in email generation.
# It includes functionalities from PublicationsHelper to create a list of author names
# formatted as a single string.
#
# Included Modules:
# - PublicationsHelper: Provides helper methods for dealing with publications.
#
# Methods:
# - all_authors_email(publication): Returns a comma-separated string of all authors'
# names associated with a given publication.
#
# Example Usage:
# ```
# publication = Publication.find(1)
# authors_string = all_authors_email(publication)
# ```
#
# Note: This helper is intended to be used within the context of Rails' ActionMailer.

module MailerHelper
include PublicationsHelper

# Returns a comma-separated string of all authors' names associated with the given publication.
#
# @param publication [Publication] The publication whose authors' names are to be returned.
# @return [String] A comma-separated string of author names.
def all_authors_email(publication)
return '' if publication.blank? || publication.author_first_name.nil? || publication.author_last_name.nil?

author_list = ''
size = [0, (publication.author_first_name.count - 1)].max
(0..size).each do |i|
Expand Down
63 changes: 63 additions & 0 deletions app/helpers/publications_helper.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
# frozen_string_literal: true

# PublicationsHelper Module
#
# This helper module provides utility functions for handling publications, particularly for formatting and creating
# publication details such as authors, citations, and other publication attributes.
#
# Methods:
# - all_authors(publication) : Constructs a string of all authors for a given publication
# - author_citation(publication) : Constructs a citation style string for authors
# - authors_array(publication) : Returns an array of truncated author names for a given publication
# - author_name(publication, position): Returns the name of an author at a specific position
# - author_name_citation(publication, position): Returns the citation style name of an author at a specific position
# - author_comma(publication, position): Returns the name of an author at a specific position with a comma between the last and first name
# - publications_id(id) : Returns the full URL for a given publication ID
# - create_citation(publication) : Constructs a full citation string for a given publication
# - author_or_artist_label : Returns either 'Artist' or 'Author' based on the context
#
# Private Methods:
# - preprocess_attr(publication, *attrs) : Utility method to preprocess attributes for a given publication
#

module PublicationsHelper
# Constructs a string of all authors for a given publication.
#
# @param [Object] publication
# @return [String] A string of all authors separated by commas
def all_authors(publication)
author_list = ''
size = [0, (publication.author_first_name.count - 1)].max
Expand All @@ -15,6 +39,10 @@ def all_authors(publication)
author_list
end

# Constructs a citation-style string for authors.
#
# @param [Object] publication
# @return [String] A string representation of authors in citation format
def author_citation(publication)
return '' if publication.blank? || publication.author_first_name.nil? || publication.author_last_name.nil?

Expand All @@ -39,6 +67,10 @@ def author_citation(publication)
author_list
end

# Returns an array of truncated author names for a given publication.
#
# @param [Object] publication
# @return [Array] An array of author names truncated to 12 characters
def authors_array(publication)
return [] if publication.blank? || publication.author_first_name.nil? || publication.author_last_name.nil?

Expand All @@ -50,22 +82,45 @@ def authors_array(publication)
author_array
end

# Returns the full name of an author at a specific position.
#
# @param [Object] publication
# @param [Integer] position The index of the author in the list
# @return [String] Full name of the author
def author_name(publication, position)
"#{publication.author_first_name[position]} #{publication.author_last_name[position]}"
end

# Returns the name of an author at a specific position in citation format.
#
# @param [Object] publication
# @param [Integer] position The index of the author in the list
# @return [String] Full name of the author in citation format
def author_name_citation(publication, position)
"#{publication.author_last_name[position]}, #{publication.author_first_name[position]}"
end

# Returns the name of an author at a specific position with a comma in between the last name and first name.
#
# @param [Object] publication
# @param [Integer] position The index of the author in the list
# @return [String] Full name of the author with a comma
def author_comma(publication, position)
"#{publication.author_last_name[position]}, #{publication.author_first_name[position]}"
end

# Returns the full URL for a given publication ID.
#
# @param [Integer] id The ID of the publication
# @return [String] The full URL for the publication
def publications_id(id)
"#{publications_path}/#{id}"
end

# Constructs a full citation string for a given publication.
#
# @param [Object] publication
# @return [String] A string representing the full citation
def create_citation(publication)
return if publication.nil?

Expand Down Expand Up @@ -102,12 +157,20 @@ def create_citation(publication)
return_string
end

# Returns either 'Artist' or 'Author' based on the controller context.
#
# @return [String] Either 'Artist' or 'Author'
def author_or_artist_label
params['controller'] == 'artworks' ? 'Artist' : 'Author'
end

private

# Utility method to preprocess attributes for a given publication.
#
# @param [Object] publication
# @param [Array] attrs List of attribute names to preprocess
# @return [String, nil] Preprocessed attribute value or nil if not found
def preprocess_attr(publication, *attrs)
attrs.each do |attr|
if publication.respond_to?(attr) && publication.send(attr).present?
Expand Down
33 changes: 32 additions & 1 deletion app/mailers/application_mailer.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,37 @@
# frozen_string_literal: true

# ApplicationMailer Class
# ========================
#
# The ApplicationMailer serves as the base class for all other mailers in the application.
# It sets default settings that are common to all mailers. For instance, it sets the default
# sender email address.
#
# Inherited From:
# - ActionMailer::Base: Inherits all the functionalities provided by ActionMailer.
#
# Constants:
# - None
#
# Methods:
# - None (Methods would be specific to individual mailers inheriting from this class)
#
# Environment Variables:
# - MAIL_SENDER: The default "from" email address.
#
# Example Usage:
# ```
# class MyMailer < ApplicationMailer
# def welcome_email(user)
# @user = user
# mail(to: @user.email, subject: 'Welcome to My Site')
# end
# end
# ```
#
# Note: Each specific mailer should inherit from this class to utilize the default settings.

class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
default from: ENV.fetch('MAIL_SENDER')
layout 'mailer'
end
51 changes: 48 additions & 3 deletions app/mailers/publication_mailer.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,58 @@
# frozen_string_literal: true

# PublicationMailer
# =================
# This mailer class is responsible for sending email notifications related to
# publications. It extends the ApplicationMailer, inheriting its default settings, and
# utilizes the MailerHelper for additional utility functions.
#
# Responsibilities:
# - Send confirmation email notifications when a publication is submitted.
# - Derive the sender's email and name from an environment variable, ensuring it's formatted correctly.
#
# Usage:
# Call the `publication_submit` method, providing it with the submitter and the publication.
# This sends an email to the submitter confirming the submission of their publication.
# The email also gets BCC'd to the default sender email for tracking purposes.
#
# Example:
# ```
# PublicationMailer.publication_submit(submitter, publication).deliver_now
# ```
#
# Environment Variables:
# - MAIL_SENDER: Contains the default sender's email address (and optionally the sender's name).

class PublicationMailer < ApplicationMailer
helper MailerHelper
default from: -> { ENV.fetch('MAIL_SENDER', nil) }

SUBJECT = 'Publication received for Artists, Authors, Editors & Composers'

def publication_submit(submitter, publication)
@submitter = submitter
@publication = publication
receivers = "#{submitter.email_address}, #{ENV.fetch('MAIL_SENDER', nil)}"
mail(to: receivers, subject: 'Publication received for Artists, Authors, Editors & Composers')
sender_name, sender_email = parse_default_sender
submitter_name = "#{submitter.first_name} #{submitter.last_name}"

mail(
to: email_address_with_name(@submitter.email_address, submitter_name),
bcc: sender_email,
from: email_address_with_name(sender_email, sender_name),
subject: SUBJECT
)
end

private

def parse_default_sender
default_sender = ENV.fetch('MAIL_SENDER')
raise ArgumentError, 'SMTP From address may not be blank' if default_sender.blank?

match_data = default_sender.match(/(.+?) <(.+)>/)
if match_data
[match_data[1], match_data[2]] # [sender_name, sender_email]
else
['', default_sender]
end
end
end
3 changes: 2 additions & 1 deletion app/views/publication_mailer/publication_submit.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<p>
Thank you for your submission of "<%= @publication.work_title %>" by: <%= all_authors_email(@publication) %>.<br><br>
<% work_or_other_title = @publication.work_title || @publication.other_title || "-untitled work-" %>
Thank you for your submission of "<%= work_or_other_title %>" by: <%= all_authors_email(@publication) %>.<br><br>
More information about this year's event is forthcoming. If you have any questions, please contact Melissa Norris at melissa.norris@uc.edu or (513) 556-1558.
</p>

3 changes: 2 additions & 1 deletion app/views/publication_mailer/publication_submit.text.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Thank you for your submission of "<%= @publication.work_title %>" by: <%= all_authors_email(@publication) %>.
<% work_or_other_title = @publication.work_title || @publication.other_title || "-untitled work-" %>
Thank you for your submission of "<%= work_or_other_title %>" by: <%= all_authors_email(@publication) %>.

More information about this year's event is forthcoming. If you have any questions, please contact Melissa Norris at melissa.norris@uc.edu or (513) 556-1558.
19 changes: 19 additions & 0 deletions config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false

# Configure the delivery method for ActionMailer to use SMTP.
# This tells Rails to send emails using the Simple Mail Transfer Protocol.
config.action_mailer.delivery_method = :smtp

# Configure the SMTP settings for sending email.
# These settings are specific to the production environment and utilize Postfix running on the same server.
config.action_mailer.smtp_settings = {
# 'address' specifies the address of the server that will handle email sending.
address: ENV.fetch('MAIL_SMTP_ADDRESS', 'localhost').presence || 'localhost',

# 'port' specifies which port to use on the SMTP server.
# Port 25 is the default port for SMTP servers like Postfix.
port: 25,

# 'ca_file' is the path to the certificate authority file.
# In our case, it's a self-signed certificate. This tells Rails to trust this specific certificate.
ca_file: '/etc/ssl/certs/postfix.pem'
}

# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
Expand Down
Loading

0 comments on commit 018057e

Please sign in to comment.