Rails send_file来自Paperclip的多个样式,如何避免代码重复?

时间:2012-12-28 03:29:45

标签: ruby-on-rails ruby-on-rails-3

这是我在关联模型中使用的默认代码,用于从Paperclip下载图像作为save_to。

months_controller

def download
  @wallpaper = Wallpaper.find(params[:wallpaper_id])
  @month = @wallpaper.months.find(params[:id])

  send_file @month.wallpaper_picture.path,
              :filename => @month.wallpaper_picture_file_name,
              :type => @month.wallpaper_picture_content_type,
              :disposition => 'attachment'
end

路线

resources :wallpapers do  
  resources :months  
end  
match 'wallpaper/:wallpaper_id/download/:id' => 'months#download', :as => :download

查看/月/索引

- @months.each do |month|  
  = link_to 'default', download_path(month.wallpaper_id, month.id) 

但我的应用程序在我的模型中声明了近6个Paperclip不同的样式,每个样式都必须可下载。为此,我做了这个(我将只展示6个代码块中的2个):

months_controller

  def download_iphone4
    @wallpaper = Wallpaper.find(params[:wallpaper_id])
    @month = @wallpaper.months.find(params[:id])

    @month = 'public/system/wallpaper_pictures/' + @month.id.to_s + '/iphone4/' + @month.wallpaper_picture_file_name
    send_file @month,
              :disposition => 'attachment'
  end

  def download_iphone5
    @wallpaper = Wallpaper.find(params[:wallpaper_id])
    @month = @wallpaper.months.find(params[:id])

    @month = 'public/system/wallpaper_pictures/' + @month.id.to_s + '/iphone5/' + @month.wallpaper_picture_file_name
    send_file @month,
              :disposition => 'attachment'
  end 

  def download_ipad ...
  def download_1440 ...
  def download_1680 ...
  def download_1920 ...
  etc ...

路线

match 'wallpaper_pictures/:wallpaper_id/iphone4/:id' => 'months#download_iphone4', :as => :download_iphone4  
match 'wallpaper_pictures/:wallpaper_id/iphone5/:id' => 'months#download_iphone5', :as => :download_iphone5  
match 'wallpaper_pictures/:wallpaper_id/ipad4/:id' => 'months#download_ipad', :as => :download_ipad  
match 'wallpaper_pictures/:wallpaper_id/1440/:id' => 'months#download_1440', :as => :download_1440  
match 'wallpaper_pictures/:wallpaper_id/1680/:id' => 'months#download_1680', :as => :download_1680  
match 'wallpaper_pictures/:wallpaper_id/1920/:id' => 'months#download_1920', :as => :download_1920  

视图/月/索引

- @months.each do |month|  
     = link_to 'iphone4', download_iphone4_path(month.wallpaper_id, month.id) 
     = link_to 'iphone5', download_iphone5_path(month.wallpaper_id, month.id) 
     = link_to 'ipad', download_ipad_path(month.wallpaper_id, month.id) 
     = link_to '1440', download_1440_path(month.wallpaper_id, month.id) 
     = link_to '1680', download_1680_path(month.wallpaper_id, month.id) 
     = link_to '1920', download_1920_path(month.wallpaper_id, month.id) 

这是我的问题:
1)我能以更清洁/更好的方式做到吗? 2)我必须将块从控制器移动到模型或新控制器吗? 3)在代码的第一个和默认方法中有一些哈希,如:

:filename => @month.wallpaper_picture_file_name,  
:type => @month.wallpaper_picture_content_type  

但在另一种方法中,我意识到我不需要使用它们。这些哈希是否必要? 4)我称之为'哈希斯'。这是对的吗?还有其他任何修正吗?


PD:如果send_file在Production中失败,请将其更改为send_data或
在config / production.rb中注释掉这一行

config.action_dispatch.x_sendfile_header = "X-Sendfile"  

send_file just sends an empty file

1 个答案:

答案 0 :(得分:3)

将您的控制器代码重构为:

def download_iphone4
  send_file (myfile params, :iphone4), :disposition => 'attachment'
end

def download_iphone5
  send_file (myfile params, :iphone5), :disposition => 'attachment'
end 

def download_ipad ...
def download_1440 ...
def download_1680 ...
def download_1920 ...


private 

def myfile params, style
  @wallpaper = Wallpaper.find(params[:wallpaper_id])
  @month = @wallpaper.months.find(params[:id])
  'public/system/wallpaper_pictures/' + @month.id.to_s + "/#{style}/" +@month.wallpaper_picture_file_name
end

或者,您可以使用您的路线修改和控制器进一步干这个:

<强>的routes.rb

match 'wallpaper/:wallpaper_id/download/:id/:style' => 'months#download', :as => :download

<强>控制器

def download
  send_file (myfile params), :disposition => 'attachment'
end 


private 

def myfile params
  @wallpaper = Wallpaper.find(params[:wallpaper_id])
  @month = @wallpaper.months.find(params[:id])
  'public/system/wallpaper_pictures/' + @month.id.to_s + "/#{params[:style]}/" +@month.wallpaper_picture_file_name
end

并从您的观点生成路径,如:

 = link_to 'iphone4', download_path(month.wallpaper_id, month.id,'iphone4') 
 = link_to 'iphone5', download_path(month.wallpaper_id, month.id,'iphone5') 

在上述两种情况下,您都可以将私人方法相应地移动到壁纸/月模型。


  

3)在代码中的第一个和默认方法中有一些哈希值   像:

     

:filename =&gt; @ month.wallpaper_picture_file_name,:type =&gt;   @ month.wallpaper_picture_content_type

     

但在另一种方法中,我意识到我不需要使用它们。是   那些哈希需要吗?

:filename让您可以控制作为附件发送的文件的文件名,您可以修改它并提供与实际文件不同的文件名。默认情况下,它将返回附件及其实际文件名。

:类型再次类似,你可以强制它到其他内容类型;但是,由于您已将文件渲染为附件,因此不会对此产生太大影响。

它们不是哈希,它们是哈希的关键值,或者在这里可以简单地视为属性。