samlester
samlester

Reputation: 335

Duplicating a record with a Paperclip attachment

I'm creating an action which duplicates an item and then allows the user to edit it and save it back to the database.

I've written the following method in my controller and it mostly works apart from the Paperclip attachment which won't move across for some reason.

def duplicate
  existing_event = Event.find(params[:id])
  @event = Event.new(existing_event.attributes)

  render action: 'new'
end

I've seen this question where the person is using .dup but I can't seem to get that working in a situation where the user edits the new item before saving.

I also tried using something like @event.image = existing_event.image but that didn't have any effect either.

This is what my create method looks like:

def create
  @event = Event.create(event_params)

  if @event.save
    redirect_to events_path, notice: "Event was successfully created."
  else
    render action: 'new'
  end
end

If it makes any difference I'm using S3 for the image uploads too and it doesn't really matter to me if there are multiple copies of the image up there.

Can anyone help? Thanks!

Upvotes: 4

Views: 1881

Answers (2)

Brendon Muir
Brendon Muir

Reputation: 4612

Here's a little snippet I use in an initialiser:

module Paperclip
  class HasAttachedFile
    def define_with_extensions
      define_without_extensions
      define_dup_override
    end

    alias_method_chain :define, :extensions

    private

    def define_dup_override
      name = @name
      @klass.send :define_method, "dup" do
        copy = super()
        self.class.attachment_definitions.each do |name, options|
          ivar = "@attachment_#{name}"
          copy.instance_variable_set(ivar, nil)

          copy.send(name).assign send(name)
        end

        copy
      end
    end
  end
end

This will assign the files from the old record to the new record programatically without knowing what the actual attachment definitions are.

Upvotes: 2

Ruby Racer
Ruby Racer

Reputation: 5740

Passing the attachment params does just that: pass the params.
You need to pass the file itself.
Below you get the idea how to do it, not tested it, but you can play around it and make it work, it shouldn't be that hard.

On new action:

existing_event = Event.find(params[:id])
@event = Event.new(existing_event.attributes)

@event.image = File.open(existing_event.image.path,'rb')

render :action => 'new'

Also:
Check in your create action, you have a slight mistake, calling create and save for the same record - this is redundant. You should call @event=Event.new(event_params) and then if @event.save.

Upvotes: 3

Related Questions