Module: Controllers::Destroyable
- Extended by:
- ActiveSupport::Concern
- Included in:
- ActivityTypesController, AddressesController, AudiencesController, BankAccountsController, BanksController, CampaignsController, CatalogsController, CommunicationsController, CreditMemosController, CustomerFiltersController, DataDictionarySetsController, EmailPreferencesController, EmailTemplatesController, EmployeeReviewsController, ItemsController, LedgerAccountsController, LedgerClosingPeriodsController, LedgerCompanyAccountsController, LedgerProjectsController, LineItemsController, MailingsController, OppFunnelsController, OutgoingPaymentsController, PackagingsController, PraisesController, PurchaseOrdersController, ReceiptsController, RevenuesController, RmasController, RolesController, SpiffsController, SqlReposController, StoresController, StrengthsController, TaxExemptionsController, TaxRatesController, TopicsController, UploadsController, VideosController, VouchersController, WarehousePackagesController
- Defined in:
- app/concerns/controllers/destroyable.rb
Overview
Shared destroy action for CRM controllers: finds the record, checks
authorization, destroys it, and redirects with a success/error flash.
Aborted destroys (dependent records, FK restrictions) are surfaced as
friendly error messages instead of 500s.
Instance Method Summary collapse
-
#destroy ⇒ void
Standard
destroyaction — delegates to #perform_destroy with the controller's model class and any redirect options fromparams[:destroy]. -
#perform_destroy(record_class, options = nil) ⇒ void
Destroy the record identified by
params[:id]and redirect.
Instance Method Details
#destroy ⇒ void
This method returns an undefined value.
Standard destroy action — delegates to #perform_destroy with the
controller's model class and any redirect options from params[:destroy].
18 19 20 |
# File 'app/concerns/controllers/destroyable.rb', line 18 def destroy perform_destroy controller_name.classify.constantize, params[:destroy] end |
#perform_destroy(record_class, options = nil) ⇒ void
This method returns an undefined value.
Destroy the record identified by params[:id] and redirect.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'app/concerns/controllers/destroyable.rb', line 30 def perform_destroy(record_class, = nil) ||= {} @error_msg = [] record_identifier = "#{record_class.name.titleize} record id #{params[:id]}" record_instance_name = "@#{record_class.name.tableize.singularize}" begin record = instance_variable_get(record_instance_name) || record_class.find(params[:id]) :destroy, record destroyed = record.destroy @error_msg += record.errors. # A `dependent: :restrict_with_error` in the cascade aborts the destroy and # adds its error to the *dependent* record, not to `record` — so without this # guard an aborted destroy (returns false, no error on `record`) would be # reported as a success. (AppSignal #6138.) @error_msg << "It has dependent records that must be removed first." if !destroyed && @error_msg.empty? instance_variable_set(record_instance_name, record) rescue ActiveRecord::RecordNotFound @error_msg << "#{record_identifier} not found." rescue CanCan::AccessDenied @error_msg << "Insufficient permissions to destroy #{record_identifier}" rescue ActiveRecord::DeleteRestrictionError => e # A dependent association declared `restrict_with_exception` still has rows. # Surface a friendly message instead of a 500. (AppSignal #6138.) @error_msg << "It has dependent #{e.[/dependent (.+)\z/, 1] || 'records'}." rescue ActiveRecord::InvalidForeignKey # A database-level restrictive foreign key still has child rows. Surface # the same friendly failure as model-level delete restrictions. @error_msg << "It has dependent records that must be removed first." end if @error_msg.empty? flash[:info] = "#{record_identifier} was deleted successfully." redir_url = [:success_url] else flash[:error] = "#{record_identifier} could not be deleted. #{@error_msg.join(',')}" redir_url = [:error_url] end redir_url ||= [:redir_url] redir_url ||= url_for(action: :index) # Redirection will be either succes/error url, or a generalized redir url option, or the index action redirect_to_return_path_or_default redir_url end |