简体   繁体   English

通过 Paperclip 上传图像而不保存对象

[英]Upload image through Paperclip without saving object

I'm working in Rails and I have two models, a prelaunch and an initiative.我在 Rails 工作,我有两个模型,一个预发布模型和一个计划模型。 Basically I want a user to be able to create an initiative using the attributes of the prelaunch.基本上,我希望用户能够使用预发布的属性创建计划。 Basically what I want to have happen is when a user visit's their prelaunch and is ready to turn it into an initiative, it brings them to a form that has their prelaunch information already populated and they can just add the additional info.基本上我想要发生的是当用户访问他们的预发布并准备将其转变为计划时,它会将他们带到一个表单,其中已经填充了他们的预发布信息,他们可以添加额外的信息。 I've managed to do this for every attribute so far except for the attached image, called :cover_image.到目前为止,除了附加的图像(称为 :cover_image)外,我已经设法为每个属性执行此操作。

I think the problem is that I'm setting the initiative's cover_image to the prelaunch's cover_image on the new action of my controller, but because this is the new action and not create, I'm not saving the initiative yet.我认为问题在于我在控制器的新操作上将倡议的 cover_image 设置为启动前的cover_image,但由于这是新操作而不是创建,我还没有保存倡议。 I think this means the cover_image isn't getting reuploaded yet, so @iniative.cover_image.url doesn't point to anything.我认为这意味着 cover_image 还没有被重新上传,所以 @iniative.cover_image.url 没有指向任何东西。 It also doesn't appear to be prepopulating the file field of my form with anything.它似乎也没有用任何东西预先填充我的表单的文件字段。

I'm not entirely sure how feasible all of this is, but it's what the client asked for so I'm trying to make it work for them.我不完全确定所有这一切的可行性,但这是客户要求的,所以我试图让它为他们工作。

Here's my controller:这是我的控制器:

def new
  @initiative = Initiative.new
  populate_defaults(@initiative)
  @initiative.build_location
  3.times{ @initiative.rewards.build }
  @initiative.user = current_user
  if !params[:prelaunch_id].nil? && !params[:prelaunch_id].empty?
    # if user is transferring a prelaunch, assign its attributes to the intiative
    @prelaunch = Prelaunch.find(params[:prelaunch_id])
    @initiative.assign_attributes(title: @prelaunch.title,
                                teaser: @prelaunch.teaser,
                                category: @prelaunch.category,
                                funding_goal: @prelaunch.funding_goal,
                                term: @prelaunch.campaign.term,
                                story: @prelaunch.story,
                                location: @prelaunch.campaign.location,
                                video_url: @prelaunch.video_url,
                                EIN: @prelaunch.campaign.EIN,
                                nonprofit: @prelaunch.nonprofit,
                                organization_name: @prelaunch.campaign.organization.name)
  end
end

Edit:编辑:

Thanks to peterept's answer below I've managed to get the prelaunch cover_image into the form and into the create action of the initiatives controller.感谢下面 peterept 的回答,我已经成功地将启动前的 cover_image 放入表单并放入了计划控制器的创建操作中。 The problem now is that everything seems to work perfectly in the create action: the initiative gets the prelaunch's cover image, it saves without error, and it redirects to the show action.现在的问题是,在 create 操作中一切似乎都运行良好:该计划获得了预发布的封面图像,它无误地保存,然后重定向到 show 操作。

UNFORTUNATELY, By the time it reaches the show action of the controller, @initiative.cover_image is set to the default again.不幸的是,当它到达控制器的显示动作时,@initiative.cover_image 再次设置为默认值。 I can't figure out what could possibly be happening between the successful create action and the show action.我无法弄清楚成功的创建操作和显示操作之间可能会发生什么。

Here are the create and show actions of the initiatives controller:以下是计划控制器的创建和显示操作:

  def create
    if !params[:initiative][:prelaunch_id].nil? && !params[:initiative][:prelaunch_id].empty?
      @prelaunch = Prelaunch.find(params[:initiative][:prelaunch_id]) # find the prelaunch if it exists
    end
    @initiative = Initiative.new(initiatives_params)
    @initiative.user = current_user
    begin
      @payment_processor.create_account(@initiative)
      if @initiative.save
        # @prelaunch.destroy # destroy the prelaunch now that the user has created an initiative
        flash[:alert] = "Your initiative will not be submitted until you review the initiative and then press 'Go Live' on the initiative page"
        redirect_to initiative_path(@initiative)
      else
        flash[:alert] = "Initiative could not be saved: " + @initiative.errors.messages.to_s
        render :new
      end
    rescue Exception => e
      logger.error e.message
      flash[:error] = "Unable to process request - #{e.message}"
      render :new
    end
  end

  def show
    @initiative = Initiative.find(params[:id])
    @other_initiatives = Initiative.approved.limit(3)
  end

And here is the initiatives_params method from the same controller:这里是来自同一个控制器的 Initiatives_params 方法:

def initiatives_params
  initiative_params = params.require(:initiative).permit(
    :terms_accepted,
    :title,
    :teaser,
    :term,
    :category,
    :funding_goal,
    :funding_type,
    :video_url,
    :story,
    :cover_image,
    :nonprofit,
    :EIN,
    :role,
    :send_receipt,
    :organization_name,
    :crop_x, :crop_y, :crop_h, :crop_w,
    location_attributes: [:address],
    rewards_attributes: [:id, :name, :description, :donation, :arrival_time, :availability, :_destroy, :estimated_value])
  if @prelaunch.media.cover_image
    initiative_params[:cover_image] = @prelaunch.media.cover_image
  end
  initiative_params
end

You can pass the Image URL and display it on the page.您可以传递图像 URL 并将其显示在页面上。

The user can then override this by uploading a new image (as per normal).然后用户可以通过上传新图像(按照正常方式)来覆盖它。

In you're create action, if they have not supplied a new image, then set it to the one in the assocoiated prelaunch - you'd want to copy the original so it doesn't get replaced if they upload a new one.在您创建操作中,如果他们未提供新图像,则将其设置为相关预启动中的图像 - 您希望复制原始图像,以便在他们上传新图像时不会被替换。 (If you don't know which was the prelaunch, you could pass the ID down to the page). (如果您不知道哪个是预启动,您可以将 ID 传递给页面)。

I was able to make it work by saving the Paperclip object only.我只能通过保存 Paperclip 对象来使其工作。 This is my model:这是我的模型:

class Grade < ActiveRecord::Base
  has_attached_file :certificate
end

If I run the following:如果我运行以下命令:

@grade.certificate = new_file
@grade.certificate.save

It saves/overwrite the file, but don't update the Grade object.它保存/覆盖文件,但不更新Grade对象。

Versions: ruby-2.3.8 , Rails 4.2.11.3 and paperclip (4.3.6)版本: ruby-2.3.8Rails 4.2.11.3paperclip (4.3.6)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM