1

I've got a hippa compliant app I'm working on and as part of it I want to use the AA comments as a nested resource / commit system; if there's no comment the create or update should be rejected. I have other nested resources working (including nested within nested resources saving); the following works on update but not on new - on new I'm getting an error that a comments.resource can't be blank.

I've got the comments_attributes within the permit params; here is admin/prescription.rb:

ActiveAdmin.register Prescription do

    menu :parent => "Treatments", :priority => 2

    permit_params :treatment_id, :hours, :summary, :product_id, :prescription_date, prescribed_tensions_attributes: [:id, :location, :force, :position, :prescription_id, :created_at, :_destroy], comments_attributes: [:id, :namespace, :body, :resource_id, :resource_type, :author_id, :author_type]


    before_filter :only => [:show, :destroy, :edit, :update] do
        # @prescription = Prescription.unscoped.includes(:prescribed_tensions).find(params[:id])
        @prescription = Prescription.unscoped.includes(:product, :prescribed_tensions, :patient, :doctors).find(params[:id])
    end




    form do |f|
        f.inputs "Prescribed Dose" do
            f.input :treatment, :as => :select, input_html: {class: 'select2able'}
            f.input :prescription_date,  as: :date_time_picker
            f.input :hours
            f.input :summary, :as => :rich, :config => { :width => '79%', :height => '150px' }

            f.has_many :prescribed_tensions, :allow_destroy => true do |g|
                g.input :location, :as => :select,  input_html: {class: 'select2able'}, collection: BaseProduct.locations
                g.input :force
                g.input :position
            end
        end

        f.inputs "Add A Comment" do
            f.semantic_fields_for :comments, ActiveAdmin::Comment.new do |c|
                c.inputs :class => "" do
                c.input :body, :label => "Comment", :input_html => { :rows => 4 }
            end
          end
        end

         f.actions
    end






    controller do



        def setup_comments
            klassname = self.resource_class.name.underscore
            if params[klassname][:comments_attributes]['0']['body'].blank?
                err = "A comment must be added to #{params[:action]} this #{klassname}."
            else
                params[klassname][:comments_attributes]['0']['namespace'] = 'admin'
                params[klassname][:comments_attributes]['0']['author_id'] = current_admin_user.id
                params[klassname][:comments_attributes]['0']['author_type'] = 'AdminUser'
            end
            if !err.nil?
                params[:error] = err
            end
            return 
        end


        def update(options={}, &block)
            setup_comments
            # save resource
            if params[:error].nil?
                super
                if resource.errors.any?
                    params[:error] = resource.errors.full_messages.first
                end
            end
            # see if any error messages
            if !params[:error].nil?
                redirect_to({ action: 'edit' }, alert: params[:error])
            end

        end


        def create(options={}, &block)
            setup_comments
            if params[:error].nil?
                super

                if resource.errors.any?
                    params[:error] = resource.errors.full_messages.first
                end



            end
            if !params[:error].nil?
                redirect_to({ action: 'index' }, alert: params[:error])
            end

        end


    end

end

And within the model/prescription.rb:

class Prescription < ActiveRecord::Base
  belongs_to :treatment

  has_one :product, through: :treatment
  has_one :patient, through: :product
  has_many :doctors, through: :patient
  has_many :prescribed_tensions, dependent: :destroy 
  accepts_nested_attributes_for :prescribed_tensions, :allow_destroy => true

  has_many :comments, as: :resource, dependent: :destroy, class_name: 'ActiveAdmin::Comment'
  accepts_nested_attributes_for :comments

  def to_s
    "#{self.prescription_date.strftime('%Y-%m-%d')} : #{self.product}"
    end

  end

With the above I get:

  #<Prescription:0x007fb402700f90
   id: nil,
   hours: 12,
   summary: "",
   prescription_date: Mon, 15 May 2017 09:31:00 EDT -04:00,
   created_at: nil,
   updated_at: nil,
   treatment_id: 6>,
 @details={:"comments.resource"=>[{:error=>:blank}]},
 @messages={:"comments.resource"=>["can't be blank"]}>

I'm attempting as well to do this by hand (ie @prescription=Prescription.new(permitted_params[:prescription]) and doing the same with building @comment, but even though I'm setting

@comment.resource = @prescription -- I still can't save @prescription because comments.prescription is blank; as @prescription hasn't been saved yet.

I'm sure I'm missing something ridiculous here, but uncertain what that might be....?

grimmwerks
  • 491
  • 1
  • 6
  • 21

1 Answers1

2

For those who care, the following is how I fixed the above; I have a successful save going to the index page (which, for the hippa resources are blank) rather than the show page. I've still yet to implement a popup comment text input for delete. I've also written the following as generic for any resource -- would LOVE to be able to override some of the AA resources (not all) and implement this in shared code, but couldn't figure that out either.

    controller do
        # hippa compliant blank
        def apply_filtering(chain)
            if params['q'].blank?
                @search = chain.ransack({})
                chain.none
            else
                super
            end 
        end

        def setup_comments
            klassname = self.resource_class.name.underscore
            if params[klassname][:comments_attributes]['0']['body'].blank?
                err = "A comment must be added to #{params[:action]} this #{klassname}."
            else
                params[klassname][:comments_attributes]['0']['namespace'] = 'admin'
                params[klassname][:comments_attributes]['0']['author_id'] = current_admin_user.id
                params[klassname][:comments_attributes]['0']['author_type'] = 'AdminUser'
            end
            if !err.nil?
                params[:error] = err
            end
            return 
        end


        def update(options={}, &block)
            setup_comments
            # save resource
            if params[:error].nil?
                super
                if resource.errors.any?
                    params[:error] = resource.errors.full_messages.first
                end
            end
            # see if any error messages
            if !params[:error].nil?
                redirect_to({ action: 'edit' }, alert: params[:error])
            end

        end


        def create
            setup_comments
            if params[:error].nil?
                resource = self.resource_class.new(permitted_params[self.resource_class.name.underscore.to_sym])
                @comment=ActiveAdmin::Comment.new(permitted_params[self.resource_class.name.underscore.to_sym][:comments_attributes]['0'])
                @comment.resource = resource
                resource.comments.first.resource = resource

                if resource.valid?
                    resource.save
                else
                    if resource.errors.any?
                        params[:error] = resource.errors.full_messages.first
                    end
                end

            end

            if !params[:error].nil?
                redirect_to({ action: 'index' }, alert: params[:error])
            else
                redirect_to({ action: 'index' }, alert: "#{resource_class} was successfully saved with comment.")
            end


        end
   end
grimmwerks
  • 491
  • 1
  • 6
  • 21