0
votes

I have a content table with a paperclip image attachment along with some user-selected cropping settings:

create_table "content", force: true do |t|
    t.string   "title"
    t.string   "image_file_name"
    t.string   "image_content_type"
    t.integer  "image_file_size"
    t.datetime "image_updated_at"
    t.integer  "crop_x"
    t.integer  "crop_y"
    t.integer  "crop_w"
    t.integer  "crop_h"
end

In order to process the user-specified image cropping on the server-side, I have a custom paperclip processor, which I sourced from here:

module Paperclip
  class CustomCropper < Thumbnail
    def initialize(file, options = {}, attachment = nil)
      super
      @current_geometry.width = target.crop_w
      @current_geometry.height = target.crop_h
    end
    def target
      @attachment.instance
    end
    def transformation_command
      crop_command = [
          '-crop',
          "#{target.crop_w}x" \
          "#{target.crop_h}+" \
          "#{target.crop_x}+" \
          "#{target.crop_y}",
          '+repage'
      ]
      crop_command + super
    end
  end
end

My problem is that the crop_x,y,w,h params are parsed after the image attachment, therefore the custom paperclip processor sees nil for all the fields and doesn't crop the image properly.

# rails processes the image_xxx params before the crop_xxx params
@content = Content.new(content_params)

Is there a clean way to tell Rails to process the crop-boundary fields before the attachment image? Or is there a different solution that essentially accomplishes this?

1

1 Answers

2
votes

For the life of me, I couldn't figure out a "clean" way. What I ended up doing was saving the crop_ values before calling an update/save with the attachment.

For example:

def update

  if article_params[:image_crop_y].present?
    @article.image_crop_y = article_params[:image_crop_y]
    @article.image_crop_x = article_params[:image_crop_x]
    @article.image_crop_w = article_params[:image_crop_w]
    @article.image_crop_h = article_params[:image_crop_h]
    @article.save
  end

  if @article.update(article_params)
    ...
  end

end

Like I said, not the "cleanest" way, but it was effective for me.