trestle icon indicating copy to clipboard operation
trestle copied to clipboard

Best approach for nested models?

Open subdigital opened this issue 6 years ago • 3 comments

I have a few nested resources (including a hierarchy of the same model) and I was wondering what the best approach for handling this is.

Currently I am overriding large parts of the controller to redirect to to the right place after certain actions (like delete, for instance) and to insert the parent record into the breadcrumb trail.

Here's an example:

# Activities Admin
  controller do
    def index
      # shouldn't get here because the index listing is part of the parent record admin
      redirect_to Trestle.admins['programs'].path
    end

    def destroy
      instance = admin.find_instance(params)
     # save the parent so we can redirect there instead of the index for this resource
      program = instance.program
      success = admin.delete_instance(instance)
      respond_to do |format|
        format.html do
          if success
            flash[:message] = flash_message("success.destroy", default: "The %{model_name} was successfully deleted.")
           # here's the custom redirect
            redirect_to program_activities_path(program)
          else
            flash[:error] = flash_message("failure.destroy", default: "Could not delete %{model_name}.")
            redirect_to admin.path(:edit, id: instance)
          end
        end
        format.json { head :no_content }
        format.js
      end
    end

    def breadcrumbs
      @breadcrumbs ||= Trestle::Breadcrumb::Trail.new(Trestle.config.root_breadcrumbs).tap do |trail|
        # insert the parent program
        if instance.try(:program)
          trail.append(
            instance.program.name,
            program_activities_path(instance.program)
            )
        end

        # and the parent model, for single model hierarchies
        if instance.parent
          trail.append(
            instance.parent.name,
            activity_path(instance.parent)
            )
        end
      end
    end

    # helper methods to get paths for other resources
    def activity_path(activity)
      Trestle.admins['activities'].path(:show, id: activity)
    end

    def program_activities_path(program)
      Trestle.admins['programs'].path(:show, id: program, anchor: '!tab-activities')
    end
end

I'm doing something similar in a few places and was wondering if there's a better way I'm missing, or if this isn't really handled properly yet.

Thanks!

subdigital avatar Sep 28 '17 16:09 subdigital

I'm planning on implementing a "subresource" feature at some stage. However you are correct that this isn't currently handled properly, and something like you have is probably the best solution so far.

spohlenz avatar Oct 03 '17 03:10 spohlenz

I appreciate the feedback! I know it's still pretty early, but I've enjoyed using Trestle so far. 👍

subdigital avatar Oct 03 '17 03:10 subdigital

I needed a solution for subresources too and used return_to for the redirects which really simplified the code above. For destroy e.g., the code was return_to(on: :destroy) { :back }.

https://github.com/TrestleAdmin/trestle/blob/fbcc5ecbd95c0abc9955a1569ab4999d16a19411/lib/trestle/resource/builder.rb#L97

Commenting here in case someone needs it in the future.

sorich87 avatar Aug 30 '21 06:08 sorich87