1

これは、関連付けられたモデルで、Paperclip から 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

ルート

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 つだけを示します)。

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

ルート

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 が失敗した場合は、send_data に変更するか
、config/production.rb でこの行をコメントアウトします。

config.action_dispatch.x_sendfile_header = "X-Sendfile"  

send_file は空のファイルを送信するだけです

4

1 に答える 1

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

または、ルートの変更とコントローラーを次のように使用して、これをさらに DRY できます。

ルート.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 => @month.wallpaper_picture_file_name, :type => @month.wallpaper_picture_content_type

しかし、他の方法では、それらを使用する必要がないことに気付きました。それらのハッシュは必要ですか?

:filename を使用すると、添付ファイルとして送信するファイルのファイル名を制御できます。変更して、実際のファイルとは異なるファイル名を付けることができます。デフォルトでは、実際のファイル名で添付ファイルを返します。

:type も同様に機能します。他のコンテンツ タイプに強制することができます。ただし、ファイルを既に添付ファイルとしてレンダリングしているため、大きな影響はありません。

それらはハッシュではなく、ハッシュのキーまたは値であるか、単にここでは属性と見なすことができます..

于 2013-01-02T18:18:51.793 に答える