我试图在我的Rails应用程序中应用Jcrop,前端部分工作正常,无需在此处发布代码。问题是当我尝试创建时。 Rails由于某种原因在分配我创建的虚拟属性之前运行ThumbnailUploader中的代码。
根据我检查的内容,此行执行ThumbnailUploader代码:
@thumbnail = Thumbnail.new(thumbnail_params)
thumbnail_params 所有坐标都没问题,我查了一下,但是由于某些我不知道的原因,它没有在ThumbnailUploader中设置要裁剪的变量。
当我更新时,它按预期工作100%。我要粘贴我的 ThumbnailController ,我的缩略图模型和我的 ThumbnailUploader ,这样你们就可以检查一下:
Rails -v:4.1.6
Ruby -v:2.1.3
宝石:
ThumbnailController :
class ThumbnailsController < ApplicationController
before_action :set_thumbnail, only: [:show, :edit, :update, :destroy]
# GET /thumbnails
# GET /thumbnails.json
def index
@thumbnails = Thumbnail.all
end
# GET /thumbnails/1
# GET /thumbnails/1.json
def show
end
# GET /thumbnails/new
def new
@thumbnail = Thumbnail.new
end
# POST /thumbnails
# POST /thumbnails.json
def create
@thumbnail = Thumbnail.new(thumbnail_params)
respond_to do |format|
if @thumbnail.save
format.html { redirect_to root_url }
format.json { render :show, status: :created, location: @thumbnail }
else
format.html { render :new }
format.json { render json: @thumbnail.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /thumbnails/1
# PATCH/PUT /thumbnails/1.json
def update
@thumbnail.crop_x = thumbnail_params[:crop_x]
@thumbnail.crop_y = thumbnail_params[:crop_y]
@thumbnail.crop_w = thumbnail_params[:crop_w]
@thumbnail.crop_h = thumbnail_params[:crop_h]
respond_to do |format|
if @thumbnail.update(thumbnail_params)
Post.cached_find(@thumbnail.post.id).thumbnail.touch
format.html { redirect_to root_url, notice: 'Thumbnail was successfully updated.' }
format.json { render :show, status: :ok, location: @thumbnail }
else
format.html { render :edit }
format.json { render json: @thumbnail.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_thumbnail
@thumbnail = Thumbnail.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def thumbnail_params
params.require(:thumbnail).permit(:image, :crop_x, :crop_y, :crop_w, :crop_h)
end
end
Thumbnail.rb:
class Thumbnail < ActiveRecord::Base
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
belongs_to :post
mount_uploader :image, ThumbnailUploader
end
ThumbnailUploader:
# encoding: utf-8
class ThumbnailUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process :resize_to_fit => [50, 50]
# end
#
# Process files as they are uploaded:
process :crop
def crop
if model.crop_x.nil?
### WHERE MY PROBLEM LIVES ####
#### !!!!! model.crop_x IS ALWAYS NIL WHEN TRYING TO CREATE !!!! #####
resize_to_fill(256, 256)
convert('jpg')
manipulate! do |img|
img.crop!(0, 10, 256, 238)
end
else
#### THIS IS WHERE I WANT TO GET, I GET HERE WHEN UPDATE ####
resize_to_fill(800, 440)
convert('jpg')
manipulate! do |img|
x = model.crop_x.to_i
y = model.crop_y.to_i
w = model.crop_w.to_i
h = model.crop_h.to_i
img.crop!(x, y, w, h)
end
resize_to_fill(256, 238)
end
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename
super.chomp(File.extname(super)) + '.jpg' if original_filename
end
end
这是我的表格。 输出标记是用户选择要上传的图像后显示图像的位置,以便他可以选择要裁剪的位置:
<output id="list"></output>
<br />
<br />
<% %w[x y w h].each do |att| %>
<%= f.hidden_field "crop_#{att}" %>
<% end %>
<p><%= f.file_field :image, required: true, class: 'form-control' %></p>
<div class="actions">
<%= f.submit class: 'btn btn-success btn-block disabled', id: 'thumbnail-send' %>
</div>
<% end %>
我从Ryan Bates RailsCast #182(Revised)
跟踪了这段代码对不起,如果我错过了什么,这里已经很晚了,我在谷歌上搜索了好几个小时没有结果。希望我在这里有所帮助。
注意: 我已经尝试过做与Update操作相同的事情,它不起作用,因为rails运行:
@thumbnail = Thumbnail.new(thumbnail_params)
之前。并尝试在此行之前添加该代码,它将抛出一个错误,指出crop_x不存在。
答案 0 :(得分:1)
我找到了解决方案:
def create
@thumbnail = Thumbnail.new(
crop_x: thumbnail_params[:crop_x],
crop_y: thumbnail_params[:crop_y],
crop_w: thumbnail_params[:crop_w],
crop_h: thumbnail_params[:crop_h],
image: thumbnail_params[:image]
)
...
诀窍。 问题是哈希的顺序。 :image是哈希的第一个元素,因此在设置我创建的attr_accessors之前,Rails会读取并执行它。
所以要小心,Rails在尝试上传之前应首先设置所有内容时会做这个奇怪的事情。