Rails send_file multiple styles from Paperclip, how can I avoid code repetition?

This is the default code that I use in the associated model to load images from the Paperclip folder as save_to.

month_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 

routes

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

view / months / index

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

But my application has about 6 clips of different styles declared in my model, and each of them should be downloadable. For this, I did this (I will show only 2 of 6 blocks of code):

month_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 ... 

routes

 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 

type / month / index

 - @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) 

Here are my questions:
1) Can I make it cleaner / better?
2) Should I move blocks from my controller to a model or a new controller?
3) In the first and default method, the code has some hashes like:

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

But in another method, I realized that I do not need to use them. Are these hashes necessary?
4) I call them "hashes." Is it correct? Any other correction?


PD: if send_file does not work in Production, change it to send_data or
comment out this line in config / production.rb

 config.action_dispatch.x_sendfile_header = "X-Sendfile" 

send_file just sends an empty file

+1
ruby-on-rails ruby-on-rails-3
source share
1 answer

Restore your controller as:

 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 

or, you can further dry this with your route and controller modifications like:

routes.rb

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

controller

 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 

and generate a path from your views something like this:

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

In both cases, you can move your private method to the wallpaper / month model, respectively.


3) In the first and default method, the code has some hashes like:

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

But in another method, I realized that I do not need to use them. Are these hashes needed?

: the file name gives you control over the name of the file that you send as an attachment, you can change it and specify a different file name, not the actual file. By default, it will return the attachment with its actual file name.

: type works the same again, you can force it to use some other type of content; however, this will not affect much, since you are already transferring the file as an attachment.

They are not hashes, they are key, hash values, or can be considered simply as attributes here.

+2
source share

All Articles