alopez02
alopez02

Reputation: 1524

Dividing a Rails edit view for the purposes of UI

So I have a 'Project' model which respective db table has many attributes.

Ideally, when I hit projects/1/edit, I'd like the user to:

  1. See and be able to edit only a portion of the project attributes
  2. See a navigation menu that allows her to navigate to another view that allows to see and edit the attributes left.

All this instead of showing all the attributes in one 'edit' view.

I'm leaning to a JS solution that hides and shows specific attributes when a menu is clicked. However, I'd ideally want that the urls reflect the section the user is located for example:

Instead of a url like projects/1/edit I'd like something like: projects/1/edit/name_of_section_1 and projects/1/edit/name_of_section_2

In any case I wonder what would be the best practice when it comes to divide views like this.

UPDATE: Only a few precisions/revisions from Dan's solution below for future reference

I've used his second approach successfully revising his proposed code as follows:

Config/routes.rb revised the controller name for both routes to 'projects'

resources :projects do
    member do
      get "settings/:panel" => "projects#edit", as: :settings
      patch "settings/:panel/update" => "projects#update", as: :update_settings
    end
end

Controllers/projects_controller.rb There was some mistake in the proposed code for the edit action so I slightly changed it to make it work

  def edit
    panel = ['general', 'invitations', 'welcome_message', 'danger'].detect{|p| p == params[:panel] }
    render template: "projects/#{panel}.html.erb" if panel
  end

Upvotes: 0

Views: 40

Answers (1)

Dan
Dan

Reputation: 1256

There's a couple of ways to do this and there all equally valid. If you need all the fields filled in to create the record you'll either need to have tabbed views with javascript (bootstrap has a nice plugin for this)

To do this with custom routes you could have: resources :projects do member do get "settings" patch "update_settings" get "settings2" patch "update_settings2" end end

which would give you URLs like /projects/1/settings and projects/1/update_settings

If you have lots of panels you could do this more efficiently with something like this:

resources :projects do
  member do
    get "settings/:panel" => "settings#edit" as: :settings
    patch "settings/:panel/update" => "settings#update" as: :update_settings
  end
end

to allow for routes like /projects/1/settings/page1 and /projects/1/settings/page2

in your controller you could then have:

def edit
  if panel = ['page1', 'page2'].detect{|p| p == params[:panel] }
    render template: panel
  end
end

this checks ifs its a valid panel you've made and then renders that specific template you've created in app/view/projects/page1.html.erb

Upvotes: 1

Related Questions