Reputation: 972
I have a Web App that I developed using Ruby on Rails and all my CRUD actions are working just fine. When I create a new project, a new form is displayed and I can fill in all the fields for the new project.
Since there are so many fields that are identical for multiple projects, I'd like to add an action like "duplicate" so that I can create a new project from an existing one, that would have all form entries the same, then I'll have only minor changes to make into the new project and update it in the database.
These are my actions
class ProjectsController < ApplicationController
# GET /projects/1
# GET /projects.1.json
def index
@projects = Project.all
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @projects }
end
end
# GET /projects/1
# GET /projects/1.json
def show
@project = Project.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render :json => @project }
end
end
# GET /projects/new
# GET /projects/new.json
def new
@project = Project.new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @project }
end
end
# GET /projects/1/edit
def edit
@project = Project.find(params[:id])
end
# POST /projects
# POST /projects.json
def create
@project = Project.new(params[:project])
respond_to do |format|
if @project.save
format.html { redirect_to @project, :notice => 'Project was successfully created.' }
format.json { render :json => @project, :status => :created, :location => @project }
else
format.html { render :action => "new" }
format.json { render :json => @project.errors, :status => :unprocessable_entity }
end
end
end
# POST /projects/1
# PUT /projects/1.json
def update
@project = Project.find(params[:id])
respond_to do |format|
if @project.update_attributes(params[:project])
format.html { redirect_to @project, :notice => 'Project was successfully updated.' }
format.json { head :ok }
else
format.html { render :action => "edit" }
format.json { render :json => @project.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /projects/1
# DELETE /projects/1.json
def destroy
@project = Project.find(params[:id])
@project.destroy
respond_to do |format|
format.html { redirect_to projects_url }
format.json { head :ok }
end
end
end
How would my "duplicate" or "copy" action look like in this case?
Upvotes: 1
Views: 708
Reputation: 106912
I would try something like this:
# in the routes.rb
resources :projects do
get 'dublicate', :on => :member
end
That allow you to build links to the dublicate action like in the views like this: link_to('duplicate', dublicate_project_path(@project))
# in the controller
def dublicate
existing = Project.find(params[:id])
@project = existing.dup
respond_to do |format|
format.html { render :new }
format.json { render :json => @project }
end
end
That would duplicate (see: http://apidock.com/rails/ActiveRecord/Core/dup) the attributes of the existing project (without the id field) into an new project and than show the new page with prepopuated fields.
Upvotes: 2
Reputation: 35349
What about something like this:
def duplicate
old_project = Project.find(params[:id])
attributes = old_project.attributes.except(:id, :created_at, :updated_at)
@project = Project.new(attributes)
render :new
end
Or maybe:
def duplicate
old_project = Project.find(params[:id])
attributes = old_project.attributes.except(:id, :created_at, :updated_at)
@project = Project.new(attributes)
if @project.save
redirect_to project_path
else
render :edit
end
end
Note that in if you are using strong_params
you might have to assign the params individually to prevent a forbidden attributes error.
As pointed out in the comments, you
Upvotes: 0