Yaro Alex Shm Yaro Alex Shm - 6 months ago 11
Ruby Question

One controller, two edit actions

I want to try having two different edit actions:


  • one with nested form (
    edit
    )

  • one without (
    editclean
    )



How can I render an edit action with a different method?

My
courses_controller.rb
:

class CoursesController < ApplicationController
before_action :set_course, only: [:show, :edit, :update, :destroy]

def new
@course = Course.new
end

def edit # <<<< edit nested
@course.events.build
end

def editclean # <<<< edit only course
end

def create
@course = Course.new(course_params)
respond_to do |format|
if @course.save
format.html { redirect_to @course }
else
format.html { render :new }
end
end
end

def update
respond_to do |format|
if @course.update(course_params)
format.html { redirect_to @course }
else
format.html { render :edit }
end
end
end

private
def set_course
@course = Course.find(params[:id])
end

def course_params
params.require(:course).permit(:name, events_attributes: [:id, :starts_at])
end
end

Answer

You have a few simple changes to make. First, in your routes.rb file, you need to add the new route. The easiest way is this:

resources :courses do
  member do
    get "editclean"
  end
end

This will add an "editclean" route and automatically editclean action in your controller.

In the controller, you have the add the editclean action to your before_action handler:

before_action :set_course, only: [:show, :edit, :editclean, :update, :destroy]

You also have to create the view file editclean.html.erb. Your edit action probably shares a _form.html.erb partial with the new action. You can either add conditionals to this partial or copy the relevant bits to the new view file. Here's what your new view might look like:

<h2>Edit (clean) Course</h2>

<%= form_for @course do |f| %>
  <%= f.label :title, "Title" %>
  <%= f.text_field :title %>

  <%= f.label :start_date, "Start Date" %>
  <%= f.text_field :start_date %>

  <%= f.label :end_date, "End Date" %>
  <%= f.text_field :end_date %>

  <%= f.submit "Save" %>
<% end %>

Note that this will re-use the existing update action to save the fields. If you want special behavior (avoiding some data checks), you might want to implement an alternative action, but the basic update action frequently works exactly as expected.

When you link to this you can use the route helper that was automatically created for you, like so:

<%= link_to "Edit (clean)", editclean_course_path(@course) %>

And that's about all there is to adding a new action.

Comments