Ruby
Rails
RubyOnRails
Railsガイド

初心者がRailsガイドを1から100まで読んでみる Railsをはじめよう編その6 データの保存

5.6.コントローラでデータを保存する

前節でデータを保存するためのテーブルを作成しました。
いま、僕が作っているブログはこんな感じ。
スクリーンショット 2018-09-21 0.33.51.png

Save Articleを押したらarticlesコントローラのcreateアクションにパラメータを送るよう実装している。
現在createアクションは

articles_controller.rb
class ArticlesController < ApplicationController
    def new
    end
    def create
        render plain: params[:article].inspect
    end
end

こうなっていて、仮にパラメータの内容をそのまま表示するようになってる。
スクリーンショット 2018-09-21 0.57.37.png

これをパラメータの内容をテーブルに保存するようにつくりかえよう!

articles_controller.rb
class ArticlesController < ApplicationController
    def new
    end
    def create
        @article = Article.new(params[:article])

        @article.save
        redirect_to @article
    end
end

こうしました!

@article = Article.new(params[:article])
@articleと書くことで、自動的にarticleモデルと関連づけられるんだって。名前を合わせているから。
articleモデルというと、articlesテーブルとセットで、TitleとTextっていう項目をもっている。
だから@articleもそんなかんじ。
そいつにArticle.new(params[:article])をぶちこんでいる。

クラスとインスタンス化

オブジェクト指向の考え方なんだけど、よく言われる例が、クラスは設計図でそれを元に組み上がったものがインスタンスだ。
設計図を形にするときnewする。
Article.new(params[:article])というのはArticleという設計図をparam[:article]という内容を注入して組み立てている。
Articleってなんだ?と思うかもしれないけど、実はその設計書がこんなところに
スクリーンショット 2018-09-23 0.07.54.png

article.rb
class Article < ApplicationRecord
end

クラス名にArticleって書いてあるでしょ?
Article.newというのはこのarticle.rbに書かれているArticleという設計書を組み立てる行為なんだ。

こんな設計書いつできたんだ…と思うかもしれないけど、Articleモデルをジェネレートした時にできてた。
スクリーンショット 2018-09-21 16.55.00.png

params[:article]はcreateアクションを書き換える前にも書いてたけど、作ったフォームが送ってきたパラメータの中身だ(僕の例だとTitleのうひょーとTextのおひょーが入ってる)
パラメータをどんな内容にするかはビューで決めている。

new.html.erb
<h1>New Article</h1>
<%= form_with scope: :article, url: articles_path, local: true do |form| %>
  <p>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </p>

  <p>
    <%= form.label :text %><br>
    <%= form.text_area :text %>
  </p>

  <p>
    <%= form.submit %>
  </p>
<% end %>

モデルの内容と一致しているんだね。

つまり僕がSave Articleボタンを押した後にcreateアクション内でインスタンス化された@articleはArticle設計図をもとにできあがった、うひょーおひょー記事だということだ。

@article.save
なんとこれでうひょーおひょー記事を保存できるらしい。
@articleはarticlesテーブルと関連づいているから、こんな簡単な記述でいけるんだね。

redirect_to @article
なんとこれもめっちゃRailsが察してくれて、showアクションにリダイレクトしてくれるらしい。リダイレクト先を@articleって書くだけでだよ?
モデルにリダイレクトするってことは、それをshowしたいんでしょ?ってことなんだろう。
…Railsのこと、なんか好きになっちゃった///

showアクションってなんだよと思うかもしれないけど、ちゃんとルーティングされている。(いつのまに…)
スクリーンショット 2018-09-16 23.04.57.png
でもこれも最初のresources:articlesの時にルーティングだけされただけで、まだアクションは実装されてないからエラーになるね。

ちなみにもう一回Save Articleボタンを押すとこんなエラーが出る
スクリーンショット 2018-09-23 0.25.12.png

このエラーはstrong parametersというチェック機能に引っかかったからでているらしい。
セキュリティの観点からすると、画面で打ち込まれた文字を何でもかんでもテーブルに保存することは望ましくない。
今回うけとったパラメータをそのままnewに使っているから、おいおいちょっとまてとstrong parametersくんに呼び止められたということらしい。

こう書くといいらしいよ

articles_controller.rb
class ArticlesController < ApplicationController
    def new
    end
    def create
        @article = Article.new(article_params)

        @article.save
        redirect_to @article
    end

    private
        def article_params
            params.require(:article).permit(:title, :text)
        end 
end

article_paramsというプライベートなメソッド(このメソッドは外から呼ばれることはないからプライベートでいいね)を追加してその中でパラメータの中身を吟味している。

これでもう一回ボタンを押してみると
スクリーンショット 2018-09-23 0.34.03.png

よく見るエラーになった!(strong parametersくんには怒られなくなった)

その7
https://qiita.com/Natsuki_on_Rails/items/480db211e20c50710edc