SMALL MAKE

by EIJI NAKAI

PROGRAMING

Ruby & Rails

Rails: 1つの form_for でコンテンツとは別にFile Upload

2015-03-04 16:24

1つの form_for の中で、添付ファイルをアップロードもやりたいのだけれど、その file_field は別に form_for のコンテンツの項目でもアソシエーションでも何でもないということがあり、以下のように書いたが、うまく行かなかった。

↓View

<%= form_for @note do |f| %>
  <%= f.text_field :title %>
  <%= f.text_field :body %>
  <%= file_field_tag :attachment %>
<% end %>

↓Controller

def create
  @note = Note.new(note_params)
  respond_to do |format|
    if @note.save
      if params[:attachment]
        attachment = params[:attachment] # <= ここでファイル情報を持つオブジェクトが取得できない
        filename = attachment.original_filename # <= したがってoriginal_filenameも取得できない
        ..... 略 ......
      end
      ..... 略 ......
    end
  end
end

def note_params
  params.require(:note).permit(:title, :body)
end

上記で、attachment = params[:attachment] は、ファイル情報を持つオブジェクトが取得できない。ファイル名の文字列だけが取得されている。

attachment を form_for の傘下に含めれば、ファイル情報を持つオブジェクトが取得できる。つまり、以下のようにviewを書けばよいことはわかったが……。

<%= form_for @note do |f| %>
  <%= f.text_field :title %>
  <%= f.text_field :body %>
  <%= f.file_field :attachment %> # <= f. を付けた file_field
<% end %>

そうすると、Strong Parameter も変更か。permitを記述するのはいいことだ……などと考える。

def note_params
  params.require(:note).permit(:title, :body, :attachment)
end

いやいや、これではNoteモデルにない項目を追加することになるし、@note = Note.new(note_params) も当然エラーになってしまう。どうする?

とりあえず、以下のようにしてStrong Paramaterを別にして回避したが、これでいいのだろうか。

↓結論(今のところの)

def create
  @note = Note.new(note_params)
  respond_to do |format|
    if @note.save
      if attachment_params[:attachment]
        attachment = attachment_params[:attachment] # <= ファイル情報を持つオブジェクトが取得できた!
        filename = attachment.original_filename # <= したがってoriginal_filenameも取得OK
        ..... 略 ......
      end
      ..... 略 ......
    end
  end
end

def note_params
  params.require(:note).permit(:title, :body)
end
def attachment_params # <= コレ追加
  params.require(:note).permit(:attachment)
end