8

以下のように、Paperclip によって処理されるアタッチメントを持つstoryモデルをセットアップしました。image

class Story < ActiveRecord::Base  
  has_attached_file :image # [...]
  attr_accessible :user_id, :title, :image, :image_file_name
  belongs_to: user

  validates_presence_of :user_id
  validates :title,     :length => { :maximum => 50 }
  validates_attachment_size :image, :less_than => 2.megabytes, :unless => Proc.new { |story| story[:image].nil? }
  # [...] 
end

ストーリー フォームに入力すると、次のようになります。

<%= form_for @story, html: { multipart: true } do |f| %>
<% if @story.errors.any? %>
<div id="error-explanation">
    <ul>
        <% @story.errors.full_messages.each do |msg| %>
        <li class="error-mess">Error: <%= msg.downcase %></li>
        <% end %>
    </ul>
</div>
<% end %>

<%= f.text_field :title %></td>
<%= f.file_field :image %>
<%= f.submit t('.send') %>

<% end %>

story.title が長すぎるために検証が失敗した場合、適切なエラー メッセージ無効なタイトルが既に入力された状態でフォームが正しく再表示されますが、file_field現在は空白であり、ファイルを再選択するためにもう一度クリックする必要があります。アップロードしたい

そして、これが私のstories_controller.rbの外観です。

def create
  @story = @current_user.stories.new(params[:story]) 
  if @story.save                                                                                                                   
    redirect_to thanks_path    
  else
    # !@story.save so I render action 'new' again just to
    # bang my head against this 'anomaly' 
    render action: "new"
  end              
end

検証エラーの後、ユーザーがアップロードするファイルを再選択する必要がないようにするにはどうすればよいですか?

4

3 に答える 3

5

HTTP ファイルのアップロードがブラウザーで機能する方法では、ファイルは最初の送信時に既にアプリにアップロードされています。そのため、後で 2 回目のフォーム送信時に引き続きアクセスできるように、ファイルをどこかに保存する必要があります。(少なくとも PHP では、アップロードされたファイルは、明示的に別の場所に移動されていなければ、スクリプトの実行後に削除されます。それが RoR にも当てはまるかどうかはわかりません。)

セキュリティ上の理由から、HTML の input type=file フィールドに事前入力することはできません。また、ユーザーがファイルを再度選択した場合でも、もう一度送信する必要があります。これは、ユーザーと帯域幅の無駄です。

したがって、最初の送信時にどこかに保存するか、サーバー側で実際に検証に失敗するフォーム送信を最小限に抑えるために、送信を許可する前に(可能な限り) JavaScript を使用してクライアント側でも検証を行うようにしてください。

于 2012-06-24T18:29:30.267 に答える
1

CBroe の言うとおりです。最善の解決策は、ファイルを一時的に保存することです。これを行うには、次のようにします。 - ファイルを一時ディレクトリに移動し、アップロードしようとしていたユーザーの ID で名前を付けます。- フォームが投稿され、ファイルがアップロードされていない場合は、そのユーザーの一時ファイルを使用してみてください (存在する場合)。- ストーリーが正常に保存されたら、そのユーザーの一時ファイルを削除します。

私はそれがトリックを行うべきだと思います。

于 2012-06-28T18:19:11.690 に答える