Duplicate a rails object with associations and pap

2019-07-09 10:48发布

I have an object with several associations. Some of these associated objects have paperclip-attachments stored at S3. If I duplicate the object and the associations it works fine but the attachments are not duplicated.

This here works without getting the images:

copy_salon = @salon.dup 
copy_salon.about_us_versions = @salon.about_us_versions.collect{|about_us| about_us.dup}

I tried to get the image link like this:

copy_salon = @salon.dup 
copy_salon.about_us_versions = @salon.about_us_versions.collect{|about_us| 
                                                                  about_us_dup = about_us.dup
                                                                  if about_us.about_us_image then about_us_dup.about_us_image = about_us.about_us_image end
                                                                  if about_us.team_image then about_us_dup.team_image = about_us.team_image end
                                                                  about_us_dup
                                                                }

But then I am getting the error 'can't convert nil into String', probably because not all images are set.

2条回答
Deceive 欺骗
2楼-- · 2019-07-09 11:13

I got it simpler by overriding dup, at least for Paperclip attachments:

def dup
  duplicate = super

  # attachment_definitions is defined if model has paperclip attachments
  return duplicate unless self.class.respond_to?(:attachment_definitions)

  duplicate.tap do |d|
    self.class.attachment_definitions.keys.each do |name|
      d.send("#{name}=", send(name)) if send(name).exists?
    end
  end
end

It can be defined like this in ApplicationRecord so every model benefits from it.

查看更多
Fickle 薄情
3楼-- · 2019-07-09 11:26

Got it, not elegant but working. I had hoped dup would duplicate my object with ALL associations and attachments. Isn't there any gem for that?

copy_salon = @salon.dup 
copy_salon.about_us_versions = @salon.about_us_versions.collect{|about_us| 
                                                                  about_us_dup = about_us.dup
                                                                  unless about_us.about_us_image.url == "/about_us_images/original/missing.png" then about_us_dup.about_us_image = about_us.about_us_image end
                                                                  unless about_us.team_image.url == "/team_images/original/missing.png" then about_us_dup.team_image = about_us.team_image end
                                                                  about_us_dup
                                                                }
查看更多
登录 后发表回答