LoginSignup
61
42

More than 5 years have passed since last update.

【Rails初心者向け】form_for メソッドを5分で理解しよう!

Last updated at Posted at 2018-09-06

Rails チュートリアルを勉強していくと、
様々なわからないことに遭遇します。
特にこの form for メソッド は、かなり難しかったので、まとめてみました。

まず、なぜ難しいか?? なんですが

1. Progate で習ってない!

Progate では、form_tag メソッドでしたね。これは、全く素直なメソッドで、簡単に理解できましたが、このform-for は・・・ 
難しい!!  

form_tag じゃダメなの??
なんで??

2. form for ()

 ()の中に何書けばいいの??? 
 f. の後もよくわからない! 

3. params[:~][:~] がわからない

送信して得られるパラメータが、よくわからない! 
何で2つシンボルがあるの?

と、このように、わからないことだらけだったので
疑問を潰していこうと思います。 

❶ なんでわざわざ、form_for 使うか? 

2つの違いは、これです! 

・特定のモデルに特化したフォームを作りたい → form_for
・別になんでも良い → form_tag

rails チュートリアルだと、micropost モデルとか、userモデルなどありますね。 
このモデルに特化したかったから、form_for だったんですね。 
 
では、特化すると、どんないいことが待っているでしょうか?

(Ⅰ) モデルのインスタンスを渡すだけで、自動的にRailsが処理してくれる. (RESTfulなリソースを使っている場合)

実際のコードを見てみましょう。 

app/controllers/microposts_controller.rb
def new 
   @micropost = Micropost.new
end

app/views/microposts/new.html.erb
<%= form_for(@micropost) do |f| %>
  <%= f.label :名前 %>
  <%= f.text_field :name %>
<% end %>

もし、この@micropost がすでに保存されていた場合は、update アクション、未保存の時は、create アクションを、Rails は自動的に選んでくれるんです。

#新規作成の時、これらは同じ内容
form_for(@micropost) 
form_for(@micropost,  url: microposts_path) 
 
#上書きする時、これらは同じ内容
form_for(@micropost) 
form_for(@micropost, url: micropost_path(@micropost), html: {method: "patch"}) 

新規作成の時も、上書きする時も、どちらも同じ form_for(@micropost) であれば、コードを書く量は減りますね。尚、基本動作の create, update以外を指定したい時は、url:, method: の両方を書かなければいけません。

 

(Ⅱ) ネスト化してくれる

ネスト化とは、「入れこ」のことです。コードを見てみましょう。
rails チュートリアル5章、SCSSのとこです。

.center {
  text-align: center;
}

.center h1 {
  margin-bottom: 10px;
}

これは、以下のように、ネスト化できます。

.center {
  text-align: center;
  h1 {
    margin-bottom: 10px;
  }
}

ネスト化のイメージは掴んだでしょうか?
ここでいきなりですが、rails チュートリアルで出てきた、ストロングパラメーターを覚えているでしょうか? 
  

app/controllers/microposts_controller.rb

 private
    def micropost_params
      params.require(:micropost).permit(:content, :picture)
    end
 end

これは、Strong Parameter という、安全な書き方です。(詳細は、Rails チュートリアル第7章 Strong Parameter 参照ください。)
 

こう書いてあることで
params[:micropost][:content]、params[:micropost][:picture]
 

このように、ネスト化された、パラメータを受け取ることができます。
一方、ネスト化されていない受け取り方は、下のようなコードになります。

def micropost_params
  params.permit(:content, :picture)
end

require (:micropost) がないですね。

これではネスト化されず、strong なparameter ではなくなってしまいます。
そして、このパラメーターの受け取り方は、progate でよく出てきた

params[:content], params[:picture]

になります。

form_tag ヘルパーをProgate のように使用すると、ネスト化されていないパラメータを受け取る
ことになり、webアプリの安全性に問題が出てくることになります。 

form_for メソッドは、params[:micropost][:content] のように、ネストしたパラメーターを送ってくれるので、安全性が担保されるというわけですね。

 

❷ form for () の()の中に何書けばいいの??? 

構文を書きます。

form_for (var [,opts]) do |f|
  ...body...
end 

# var: モデルオブジェクト opts: 動作オプション
  • モデルオブジェクト
    User モデルでこのform_for を使うなら、@user
    Micropost モデルなら、@micropost になりますね。

  • 動作オプション(url, html)
    create, update の機能だけであれば、不要ですね。 
    それ以外の機能の時には、記載が必要になります。

url: フォームの送信先 (名前付きルート) ex: user_path(user)
html: class, methodなどを明記します。 ex: html: {class:"~"}

❸ f. の後に何書けばいいの??? 

f とは、form の略です。
Rails チュートリアル第7章を参照しましょう。

このf オブジェクトは、HTMLフォーム要素(テキストフィールド、パスワードフィールドなど)に対応するメソッドが呼ばれると、@micropostの属性を設定するために、特別に設計されたHTMLを返します

コードをご覧ください。

<%= form_for(@micropost) do |f| %>
  <%= f.text_area :content %>
  <%= f.submit "送信" %>
<% end %>

:content のcontent とは、micropost の属性ですね。

rails g model Micropost content:text

micropost モデルを作る時に設定しました

では、f.の直後の記述は何でしょうか?一部を紹介します。

<input> <textarea> 要素を生成するメソッド

--- XXXX_field / text_area メソッド --- 

xxxx_field(obj, prop [,opts])
text_area(obj, prop [,opts])
obj: オブジェクト名(省略可) prop: プロパティ名  
opts: 要素の属性

この他にも、check_box, radio_button, select などたくさんあります。
気になる方は調べてくみてください。 

これで、form_for メソッドは完成しました。
最終的になコードは次のようになります。

<%= form_for(@micropost) do |f| %>
  <%= f.file_field :picture %>
  <%= f.text_area :content %>
  <%= f.submit "送信" %>
<% end %>

以上で、終了となります。
間違ってる所など、お気付きのことがありましたら、コメントを頂けますと幸いです。
 

 

参考文献: 
Ruby on Rails 5 アプリケーションプログラミング  
Rails ガイド
Rails チュートリアル
https://qiita.com/shunsuke227ono/items/7accec12eef6d89b0aa9

61
42
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
61
42