Проверка в activeadmin с настраиваемым действием контроллера - PullRequest
0 голосов
/ 09 января 2019

В нашем веб-приложении композиция имеет много авторов через таблицу с именем contrib . Мы хотим проверить, что админ не случайно удаляет всех авторов одной композиции в activeadmin (хотя бы один должен остаться). Если это происходит, обновление завершается неудачно с сообщением об ошибке, и представление редактирования для композиции отображается снова.

Вызов проверки модели с помощью

validates_presence_of :authors, on: :update

здесь не подходит, потому что добавление новых вкладов (то есть авторов) выполняется при вызове success.html для функции обновления контроллера activeadmin, чтобы предотвратить некоторые предыдущие ошибки, которые создавали двойные записи для авторов.

Модели:

class Composition < ApplicationRecord
  has_many :contributions
  has_many :authors, through: :contributions
end
----
class Contribution < ApplicationRecord
  belongs_to :composition
  belongs_to :author
end
----
class Author < ApplicationRecord
  has_many :author_roles, dependent: :delete_all
  has_many :contributions
  has_many :compositions, through: :contributions
end

Наш код в admin имеет некоторую фоновую логику для обработки того, что было описано ранее:

ActiveAdmin.register admin_resource_name = Composition do
  ...
  controller do
    def update
      author = []
      contribution_delete = []
      params[:composition][:authors_attributes].each do |number, artist|
        if artist[:id].present?
          if artist[:_destroy] == "1"
            cont_id = Contribution.where(author_id: artist[:id],composition_id: params[:id]).first.id
            contribution_delete << cont_id
          end  
        else
          names = artist[:full_name_str].strip.split(/ (?=\S+$)/)
          first_name = names.size == 1 ? '' : names.first
          exist_author = Author.where(first_name: first_name, last_name: names.last, author_type: artist[:author_type]).first
          author << exist_author.id if exist_author.present?
        end
      end if params[:composition][:authors_attributes] != nil
      params[:composition].delete :authors_attributes
      update! do |success, failure|
        success.html do
          if author.present?
            author.each do |id|
              Contribution.create(author_id: id, composition_id: params[:id])
            end
          end  

          if contribution_delete.present?
            contribution_delete.each do |id|
              Contribution.find(id).destroy
            end
          end
          ...
          redirect_to admin_composition_path(@composition.id)
        end
        failure.html do
          render :edit
        end
      end
    end
  end
  ...
end

Есть ли у вас какие-либо идеи, как я могу контролировать authors_attributes и выдавать флэш-сообщение типа "Должен быть хотя бы один автор", если число подлежащих удалению авторов равно числу существующих авторов?

Я подумал, что, возможно, можно обработать это до вызова update!, чтобы каким-то образом преобразовать успех в неудачу, но я понятия не имею, как.

...