rh4games
rh4games

Reputation: 972

ruby on rails create new entry

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

Answers (2)

spickermann
spickermann

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

Mohamad
Mohamad

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

Related Questions