0

この例をファイルアップローダーに使用しています。

これで次のように機能します。ファイルをアップロードすると、ファイルが保存された後、関数(do_picture_analyse)がRを呼び出し、ヒストグラムを生成します(最も単純なバージョンでは、より複雑なバージョン2のパッケージをRにインストールする必要があります)。ヒストグラムが保存されます。問題は、50個のファイルをアップロードする場合、ファイルごとにRで2つのパッケージを個別にロードするのに時間がかかることです(after_saveコールバック)。

必要なもの:ファイルをアップロードし、ファイルを保存し、[ヒストグラム]ボタンをクリックすると、データベース内のすべてのファイルに対して関数do_picture analysisが呼び出されます(一部のファイルが既に分析されているかどうかは関係ありません)。

したがって、ボタンと関数の呼び出しの間の相互作用を行う方法を知る必要があるだけで、それ以上のことは何もありません。

私のshow.html.erb:

<script id="template-download" type="text/x-tmpl">
  {% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-download fade">

       <td></td>
      <td class="name">
       <a href="{%=file.url%}" download="{%=file.name%}">{%=file.name%}</a>
      </td>
       <td class="nam">
       <a href="{%=file.url_chip_image%}" download="{%=file.name%}">{%=file.name%}</a>
      </td>


      <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>     

      <td class="Pic">
        <button class="btn btn-mini btn-info">Pic</button>    
      </td>

      <td class="Hist">
        <button class="btn btn-mini btn-primary" >Hist</button>        
      </td>

      <td class="delete">
        <button class="btn btn-mini btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}"> 
          <i class="icon-trash icon-white"></i>

        </button>
        <input type="checkbox" name="delete" value="1">
      </td>
    </tr>
    {% } %}
</script>

私のupload.rb:

def to_jq_upload
    {
      "name" => (read_attribute(:upload_file_name)).split(".").first,
      "size" => read_attribute(:upload_file_size),
      "url" => upload.url(:original),
      "delete_url" => upload_path(self),
      "delete_type" => "DELETE",
      "url_chip_image"=>read_attribute(:chip_image),

    }
  end


  after_save :do_picture_analyse


def do_picture_analyse
  if read_attribute(:chip_image)==nil

   require 'rinruby'
    myr = RinRuby.new(echo=false)

myr.filepath=upload.path(:original)
myr.fileurl=upload.url(:original)


myr.eval <<EOF
   s=read.table(filepath)
   for(j in nchar(filepath):1){
         if(substr(filepath,j,j)=="/"){      
           savepath<-substr(filepath,1,j-1)
           file.name<-filepath
           file.name<-substr(file.name,j+1,nchar(filepath)-4)

           break
         }
       }


  file.name1<-paste(file.name,"image.jpeg",sep="_")
  savepath<-paste(savepath,file.name1,sep="/")

   jpeg(filename=savepath,width=250, height=250)
   hist(s$V1) 
   dev.off()




EOF



  self.update_attributes(
    :chip_image => (((myr.fileurl).split("?").first)[6..-5]+'_image.jpeg')
  )
end

end

編集:

do_picture_analyseは、フォルダーをパラメーターとして受け取り、フォルダー全体に対して1回だけパッケージをロードすることにより、フォルダー内のすべてのファイルを分析できます。ファイル用のフォルダーは2つだけです(2つの異なるタイプのファイル、たとえば.txtファイルと.blablaファイルはtxt-Folderまたはblabla-Folderのいずれかに保存されます。フォルダのタイプもデータベースに保存されます。ボタンをクリックすると、2つのフォルダがdo_picture_analyseに渡され、すべてが実行されます。よろしくお願いします。

4

2 に答える 2

1

このための新しいルートを作成する必要があります:

resources :name_of_your_controller do
  # use this if you want a route like resources/:id/analyze (single file)
  get :analyze, on: :member 
  # use this if you want a route like resources/analyze (multiple files)      
  get :analyze, on: :collection
end

次に、コントローラーで新しいアクションを作成します。

def analyze
  # for single file analysis do something like this :
  @file = File.find( params[:id] )
  @file.do_picture_analyse
  respond_to do |format|
    # render what you need to render, js or html
  end

  # ... or do something like this for multiple file analysis :
  @files = File.where( params[:search] )
  @files.each {|f| f.do_picture_analyse )
  # etc.
end

次に、ボタンをアクションにリンクできます。

# single file
<%= link_to "Histogram", analyze_file_path( file ) %>
# multiple files
<%= link_to "Histogram", analyze_files_path( search: your_search_conditions ) %>

PS: メソッドが多くの処理能力を必要とする場合 (R を使用している場合、複雑な計算が必要であると想定します)、Worker で抽出してバックグラウンド タスクとして実行することを検討する必要があります。

編集

あなたのコメントへの応答:

このメソッドを抽出して、1 つ以上のパスを受け入れるクラス メソッドにする必要があると思います。次に、コントローラーを指すコレクション ルートを作成します。コントローラーアクションで、いくつかのパラメーターに従ってファイルをロードし、次のようにします:

# find the directories to be processed : 
paths = @files.map(&:folder_type).uniq
# pass them to your class method : 
File.do_picture_analyse(paths)

リレーション内のすべてのファイルに対して、これらの 2 つのステップを自動的に処理するクラス メソッドを作成することもできます。

def self.perform_analysis!
  paths = all.map(&:folder_type).uniq # or uniq.pluck(:folder_type) on rails >= 3.2.1
  do_picture_analyse(paths)
end

def self.do_picture_analyse( *paths )
  # call R from here
end

次に、次のことができます。

File.where( your_search_params ).perform_analysis!
于 2012-12-01T13:40:54.917 に答える
1

短くて甘い答え:あなたのshow.html.erb書き込みで:

  <td class="Hist">
    <%= link_to 'Histogram', histogram_path, ;method => :post, :class => 'btn btn-mini btn-primary" %>
  </td>

config/routes.rb次の行を追加します

post '/histogram' => 'your-controller#histogram', :as => 'histogram'

histogram_pathこれは、がという名前のコントローラーを指しyour-controller、アクションを呼び出すことを意味しhistogramます。それらをあなたの名前に置き換えてください。

そして、あなたは行く準備ができているはずです。

アクションがべき等ではないと仮定しているため、私は自由に POST アクションを提案しました。その場合は、GET を使用する必要があります。

お役に立てれば。

于 2012-12-01T15:46:10.240 に答える