[英]Paperclip dynamic styles based on polymorphic parent class doesn't work (Rails 4.2.5, Paperclip 4.3.1)
Basically I have an Image
model which polymorphically belongs to imageable
which are by far List
and Item
. 基本上,我有一个
Image
模型,该模型多态地属于imageable
对象,到目前为止,它们都是List
和Item
。 Since an image will have its own attribute and relationship, I don't want to treat images like attributes of the List
and Item
and mess it up. 由于图像将具有其自己的属性和关系,因此我不想将图像像
List
和Item
属性一样对待并将其弄乱。 So I create the Image
model. 因此,我创建了
Image
模型。
What I want to achieve is that List
should have a logo thumb image where height equals width but Item
has a different style. 我要实现的是
List
应该有一个徽标拇指图像,其中高度等于宽度,但Item
具有不同的样式。 Paperclip doc has told us to create dynamic styles using lambda
. 回形针doc告诉我们使用
lambda
创建动态样式。 So here's my Image
model: 所以这是我的
Image
模型:
class Image < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
has_attached_file :file,
:styles => lambda { |file| { thumb: (file.instance.imageable_type == "List") ? "300x300!" : "200x100!") } }
:default_url => "/images/:style/missing.png"
end
And my List
model: 而我的
List
模型:
class List < ActiveRecord::Base
def list_params
params.require(:list).permit(:title, :image_attributes)
end
has_one :image, as: :imageable
accepts_nested_attributes_for :image
validates :image, presence: true
end
And my lists_controller.rb
: 和我的
lists_controller.rb
:
class ListsController < ApplicationController
def list_params
params.require(:list).permit(:title, :image_attributes)
end
def create
@list = List.new(list_params)
if @list.save
redirect_to @list
else
render :action => "new"
end
end
end
And I have nested form in my new.html.erb
for lists. 我在
new.html.erb
嵌套了表单列表。 Everything works well if I don't use dynamic styles in Image
model. 如果我在
Image
模型中不使用动态样式 , 那么一切都会很好 。 If I do so, the imageable_type
remains nil
when the image styles are processed. 如果这样做,则在处理图像样式时
imageable_type
仍为nil
。 It is believed that the Paperclip processor comes in too early when everything related to the imageable aren't assigned. 据信,如果没有分配与可成像图像有关的所有内容,Paperclip处理器来得太早。 So the result is that I always have an image with
200x100
size even when the imageable is a List
. 因此,结果是即使可成像对象是
List
,我也总是拥有200x100
尺寸的图像。
I've been seeking around for a solution. 我一直在寻找解决方案。 But many solutions are for Rails 3 and failed in my app (like
attr_accessible
solution and any solution intending to retrieve anything about the imageable). 但是许多解决方案都是针对Rails 3的,并且在我的应用程序中失败了(例如
attr_accessible
解决方案以及任何旨在检索可成像内容的解决方案)。 Now I'd be grateful if anyone can provide a clean solution before I give in and use STI or monkey-patch Active Record. 现在,如果有人在我提供并使用STI或猴子补丁Active Record之前可以提供干净的解决方案,我将不胜感激。
The monkey-patch solution explains pretty much about why this is happening. 猴子补丁解决方案说明了为什么会发生这种情况。 But it's not easy to understand if you don't have comprehensive knowledge about Active Record.
但是,如果您不具备有关Active Record的全面知识,就很难理解。 Basically, you have to make Rails assign imageable related attributes before assigning the Paperclip ones.
基本上,在分配回形针之前,必须使Rails分配可成像的相关属性。
I've found a simpler solution thanks to @Eren CAY here . 感谢@Eren CAY 在这里,我找到了一个更简单的解决方案。 But I made some modifications for it to work better in my app.
但是我对其进行了一些修改,以使其在我的应用中可以更好地工作。
In my Image
model: 在我的
Image
模型中:
class Image < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
has_attached_file :file,
:styles => -> (file) {file.instance.get_customized_styles},
:default_url => "/images/:style/missing.png"
def get_customized_styles
raise "Imageable not found." unless imageable_type
if imageable_type == "List"
imageable_type.constantize.image_styles
else
raise "Please define styles for #{imageable_type}."
end
end
end
And in my lists_controller.rb
: 在我的
lists_controller.rb
:
class ListsController < ApplicationController
def list_params
params.require(:list).permit(:title, :description, :image_attributes)
end
def new
@list = List.new
@list.build_image
end
def create
cleaned_list_params = list_params.dup
cleaned_list_params.delete(:image_attributes)
@list = List.new(cleaned_list_params)
image_params = {imageable_type: "List", file: params[:list][:image_attributes][:file]}
@list.build_image(image_params)
if @list.save
redirect_to :action => "index"
else
render :action => "new"
end
end
end
I think the essential is the specified parameter passed to tell Image
its imageable type (no matter the parameter is a string or object or sth else). 我认为关键是传递给
Image
的可成像类型的指定参数(无论该参数是字符串,对象还是其他)。 Normally, it's only after the file attribute is assigned that other imageable related attributes are assigned. 通常,只有在分配了文件属性之后,才会分配其他可成像的相关属性。
The main differences from the original solution is that: 与原始解决方案的主要区别在于:
Image
model. Image
模型中。 List.new
as it has its own attributes. List.new
因为它具有自己的属性。 (The 'clean' process is optional, I just don't want the whole bunch of image_attributes to be passed and trigger Paperclip)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.