Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 尝试在更新后回调中重新处理图片会导致无限循环_Ruby On Rails_Ruby_Callback_Paperclip_Infinite Loop - Fatal编程技术网

Ruby on rails 尝试在更新后回调中重新处理图片会导致无限循环

Ruby on rails 尝试在更新后回调中重新处理图片会导致无限循环,ruby-on-rails,ruby,callback,paperclip,infinite-loop,Ruby On Rails,Ruby,Callback,Paperclip,Infinite Loop,我将此模型的图片附在另一个模型作品上: 这些图片有两个用途:如果is_cover设置为false,它们将显示在相关作品的图库页面中。如果is_cover设置为true,它们将被裁剪并用作列出所有作品的页面中相关作品的图标 在“工作编辑”页面上,您可以更改裁剪的x和y坐标。这意味着一旦新的坐标出现,图像应该重新处理,以便显示正确的区域 为此,我在模型上设置了两个属性,crop_x和crop_y,它们存储裁剪窗口的位置。通过更新后,我首先检查这些坐标是否已更改,如果已更改,我会告诉曲别针重新处理图像

我将此模型的图片附在另一个模型作品上:

这些图片有两个用途:如果is_cover设置为false,它们将显示在相关作品的图库页面中。如果is_cover设置为true,它们将被裁剪并用作列出所有作品的页面中相关作品的图标

在“工作编辑”页面上,您可以更改裁剪的x和y坐标。这意味着一旦新的坐标出现,图像应该重新处理,以便显示正确的区域

为此,我在模型上设置了两个属性,crop_x和crop_y,它们存储裁剪窗口的位置。通过更新后,我首先检查这些坐标是否已更改,如果已更改,我会告诉曲别针重新处理图像以正确裁剪

当运行此代码时,执行进入一个无止境的循环。我想我已经确定了原因:在更新ActiveRecord::脏属性后,例如self.crop\u x\u发生了变化?使它对开发人员更有用,但是当我调用reprocess时!在图片上,回形针本身对“我的模型”进行更改并调用“保存”,从而再次触发“更新后”回调。自从self.crop\u改变了?而self.crop___改变了吗?这是因为它们似乎只有在更新运行后才被清除一次,这会导致我的代码调用reprocess!再一次,它延续了这个无休止的循环


我已经尝试过许多类似的代码变体,但似乎都是无休止地循环,或者就是失败了。有什么方法可以让我的代码正确地执行此功能吗?

多亏了一位朋友的帮助,我找到了一种方法使其正常工作。我是这样解决的:

我在app/models/work\u picture/Recropper.rb中创建了一个新类WorkPicture::Recropper。为了进行比较,work\u picture.rb文件位于app/models/中。下面是它的代码:

class WorkPicture::Recropper
  def initialize work_picture
    @work_picture = work_picture
    @crop_x = @work_picture.crop_x
    @crop_y = @work_picture.crop_y
  end

  def recrop
    @work_picture.reload

    if @work_picture.crop_x != @crop_x || @work_picture.crop_y != @crop_y
      @work_picture.picture.reprocess!
    end
  end
end
我将控制器的更新操作更改为使用WorkPicture::Recropper:

简单地说,我所做的就是在更新属性之前将封面图片传递给重新裁剪器,这样它就有机会存储旧的裁剪坐标。更新属性后,recop方法将重新加载模型,并将属性的新值与其存储的值进行比较。如果他们改变了,它会重新处理图片

此解决方案可行,但可能不是最干净的。如果有人有更好的主意,请告诉我

class WorkPicture::Recropper
  def initialize work_picture
    @work_picture = work_picture
    @crop_x = @work_picture.crop_x
    @crop_y = @work_picture.crop_y
  end

  def recrop
    @work_picture.reload

    if @work_picture.crop_x != @crop_x || @work_picture.crop_y != @crop_y
      @work_picture.picture.reprocess!
    end
  end
end
class WorksController < ApplicationController

  # ... Other actions ...

  def update
    @work = Work.find(params[:id])
    recropper = WorkPicture::Recropper.new(@work.cover_picture)

    if @work.update_attributes(work_params)
      recropper.recrop
      redirect_to @work
    else
      render :edit
    end
  end

private

  def work_params
    params.require(:work).permit(:name, :description, :category_id, pictures_attributes: [:crop_x, :crop_y, :is_cover, :picture, :id])
  end
end