Ruby on rails Ruby on Rails-回形针和动态参数
我正在用回形针为RubyonRails编写一些图像上传代码,我有一个可行的解决方案,但它非常粗糙,所以我非常感谢关于如何更好地实现它的建议。我有一个“资产”类,包含上传图像的信息,包括回形针附件,还有一个“生成器”类,封装尺寸信息。每个“项目”都有多个资产和发电机;所有资产应根据每个发电机规定的大小调整大小;因此,每个项目都有其所有资产都应该具备的特定规模 发电机型号:Ruby on rails Ruby on Rails-回形针和动态参数,ruby-on-rails,ruby,paperclip,Ruby On Rails,Ruby,Paperclip,我正在用回形针为RubyonRails编写一些图像上传代码,我有一个可行的解决方案,但它非常粗糙,所以我非常感谢关于如何更好地实现它的建议。我有一个“资产”类,包含上传图像的信息,包括回形针附件,还有一个“生成器”类,封装尺寸信息。每个“项目”都有多个资产和发电机;所有资产应根据每个发电机规定的大小调整大小;因此,每个项目都有其所有资产都应该具备的特定规模 发电机型号: class Generator < ActiveRecord::Base attr_accessible :heig
class Generator < ActiveRecord::Base
attr_accessible :height, :width
belongs_to :project
def sym
"#{self.width}x#{self.height}".to_sym
end
end
我遇到的问题是一个鸡蛋问题:新创建的资产在正确实例化之前不知道使用哪个生成器(大小规格)。我试着使用@project.assets.build,但在资产设置其项目关联之前,回形针代码仍然被执行,而我的结果为零
“if@generators==nil”hack是这样的,因此更新方法可以工作,而不需要在控制器中进行进一步的hack
总而言之,感觉很糟糕。有谁能建议如何以一种更合理的方式写这篇文章,或者甚至是一种处理这类事情的方法吗
提前感谢!:) 我在一个项目中遇到了同样的回形针鸡/蛋问题,该项目试图使用基于多态关系关联模型的动态样式。我已根据您现有的代码调整了我的解决方案。解释如下:
class Asset < ActiveRecord::Base
attr_accessible :image, :deferred_image
attr_writer :deferred_image
has_attached_file :image,
:styles => lambda { |a| a.instance.styles }
belongs_to :project
after_save :assign_deferred_image
def styles
project.generators.each_with_object({}) { |g, hsh| hsh[g.sym] = "#{g.width}x#{g.height}" }
end
private
def assign_deferred_image
if @deferred_image
self.image = @deferred_image
@deferred_image = nil
save!
end
end
end
以及以下观点:
<%= form_for @asset do |f| %>
<%# other asset attributes %>
<%= f.label :deferred_upload %>
<%= f.file_field :deferred_upload %>
<%= f.submit %>
<% end %>
与您现有的方法完全相同,但更简洁。虽然我非常喜欢Cade的解决方案,但只是一个建议。看起来“样式”属于一个项目……那么你为什么不计算那里的生成器呢 例如:
class Asset < ActiveRecord::Base
attr_accessible :filename,
:image # etc.
attr_accessor :generators
has_attached_file :image,
:styles => lambda { |a| a.instance.project.styles }
end
class Project < ActiveRecord::Base
....
def styles
@generators ||= self.generators.inject {} do |hash, g|
hash[g.sym] = "#{g.width}x#{g.height}"
end
end
end
我刚刚解决了一个类似的问题。 在我的“样式”lambda中,我根据“类别”属性的值返回不同的样式。但问题是Image.new(attrs)和Image.update_attributes(attrs)没有按可预测的顺序设置属性,因此无法保证Image.category在调用my styles lambda之前会有一个值。我的解决方案是覆盖图像模型中的属性=(),如下所示:
class Image
...
has_attached_file :image, :styles => my_lambda, ...
...
def attributes=(new_attributes, guard_protected_attributes = true)
return unless new_attributes.is_a?(Hash)
if new_attributes.key?("image")
only_attached_file = {
"image" => new_attributes["image"]
}
without_attached_file = new_attributes
without_attached_file.delete("image")
# set the non-paperclip attributes first
super(without_attached_file, guard_protected_attributes)
# set the paperclip attribute(s) after
super(only_attached_file, guard_protected_attributes)
else
super(new_attributes, guard_protected_attributes)
end
end
...
end
这样可以确保回形针属性设置在其他属性之后,因此可以在:样式lambda中使用它们
在“手动”设置回形针属性的情况下,这显然没有帮助。但是,在这些情况下,您可以通过指定合理的顺序来帮助自己。就我而言,我可以写:
image = Image.new
image.category = "some category"
image.image = File.open("/somefile") # styles lambda can use the "category" attribute
image.save!
(回形针2.7.4、rails 3、ruby 1.8.7)虽然在哪里找到实际样式方法是一个有趣的问题,但这对新记录来说是不起作用的。在styles lambda中,
a.instance.project
将是nil
,直到记录被保存为止,因此您将在nil
上得到NoMethodError
。我编辑了我的解决方案…我确定该实例必须指向@asset变量?如果您像我一样修改控制器,那么它应该已经将项目包含在一个隐藏的实例变量中,供paperclip使用…Rails在项目模型上拍摄错误,styles action。说明:语法错误,意外的关键字\u do\u块,期望关键字\u end
这个问题及其答案对在我的应用程序中构建相同功能有很大帮助。谢谢大家!:)
def styles
(@generators || project.generators).each_with_object({}) { |g, hsh| hsh[g.sym] = "#{g.width}x#{g.height}" }
end
class Asset < ActiveRecord::Base
attr_accessible :filename,
:image # etc.
attr_accessor :generators
has_attached_file :image,
:styles => lambda { |a| a.instance.project.styles }
end
class Project < ActiveRecord::Base
....
def styles
@generators ||= self.generators.inject {} do |hash, g|
hash[g.sym] = "#{g.width}x#{g.height}"
end
end
end
def create
@project = Project.find(params[:project_id])
@asset = @project.assets.new
@asset.generators = @project.generators
@asset.update_attributes(params[:asset])
@asset.uploaded_by = current_user
end
class Image
...
has_attached_file :image, :styles => my_lambda, ...
...
def attributes=(new_attributes, guard_protected_attributes = true)
return unless new_attributes.is_a?(Hash)
if new_attributes.key?("image")
only_attached_file = {
"image" => new_attributes["image"]
}
without_attached_file = new_attributes
without_attached_file.delete("image")
# set the non-paperclip attributes first
super(without_attached_file, guard_protected_attributes)
# set the paperclip attribute(s) after
super(only_attached_file, guard_protected_attributes)
else
super(new_attributes, guard_protected_attributes)
end
end
...
end
image = Image.new
image.category = "some category"
image.image = File.open("/somefile") # styles lambda can use the "category" attribute
image.save!