「Ruby on Rails」を触ってみます。 今回はほとんどドットインストール とkindleUnlimited で学んだことの 備忘録みたいな感じです。
目次
アプリケーションの作成
アプリケーションの実行
scaffold でのテーブル設定と作成 1 2 3 rails g scaffold [モデル名] [カラム名]:[データベース型]... rails db:migrate
モデルを作成し、テーブルを作成 1 2 3 rails g model [モデル名] [カラム名]:[データベース型]... rails db:migrate
データ作成(コマンドで) 1 2 3 4 5 6 7 8 9 rails c [変数A]=[モデル名].new([カラム名]: [データ],...) [変数A].save [変数A]=[モデル名].create([カラム名]: [データ],...)
データベースの中身を操作する。 1 2 3 4 5 6 7 8 9 rails db .table .exit
コントローラを作る 作成 1 rails g controller [コントローラ名]
コントローラ名は操作対象のモデルの複数形にする。が、必須ではない。 [アプリケーションルート]\app\controllers[コントローラ名]_controller.rb、 [アプリケーションルート]\app\views[コントローラ名]が作成される
編集 [コントローラ名]_controller.rb 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class [コントローラ名]Controller < ApplicationController end class [コントローラ名]Controller < ApplicationController def index @data = [モデル名].all render 'index' render 'foo' render :json => @data end end
ルーティングを作る [アプリケーションルート]\config\routes.rb を編集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Rails .application.routes.draw do resources : [コントローラ名] [リクエストメソッド] 'アクセスされるパス' ,to: '[コントローラ名]#[関数(アクション)名]' get 'data' , to: 'data#index' root 'data#index' end
記述したルーティングを確認するときは
ビューを作る [アプリケーションルート]\app\views[コントローラ名][任意の名前].html.erb を作成する。
1 2 3 4 5 6 <h2 > Posts</h2 > <ul > <% [コントローラで定義したインスタンス変数].each do |data | %> <li > <%= data.name %></li > <% end %> </ul >
レイアウトを編集する [アプリケーションルート]\app\views\layouts[レイアウト名].html.erb を編集する。<%= yield %>
の中に各コントローラで呼び出したビュー内容が展開される。
レイアウトを選ぶ 使用するレイアウトを指定することができる。
1 2 3 4 5 6 7 8 9 10 11 12 class AController < ApplicationController layout "layout1" def index end def show render :show , layout: "layout2" end end
リンクを貼る link_to ヘルパーを使ってビューの中で以下の記述でリンクを貼る
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <%= link_to [リンクテキスト], "[リンク先]url" %> # プレフィックスの使用例 <% @datas .each do |data | %> #できる <li > <%= link_to data.title, data_path(data) %></li > #できる <li > <%= link_to data.title, data %></li > #できないみたい リンクがfoo.[データのID]になってしまう。 <li > <%= link_to data.title, foo_path(data) %></li > #できる <li > <%= link_to data.title, '/foo/' +data.id.to_s %></li > <% end %>
foo_path(data)はリンクがたとえば/foo.1
になってしまうので、使えなかった
画像を貼る ビューで image ヘルパーを使用して img タグを使用する
1 2 3 4 5 6 7 8 9 # [アプリケーションルート]\app\assets\images\a.jpgを表示する <%= image_tag 'a.jpg' %> # class1をclassに割り当てる <%= image_tag 'a.jpg' , class: class1 %> imgタグをリンクにする。 <%= link_to image_tag( 'a.jpg' ),[リンク先URL ] %>
オブジェクトと結びついたフォームを作る コントローラに関数を用意
1 2 3 def new @post = Post .new end
ビューで form_for ヘルパーを使う
new.html.erb 1 2 3 4 5 6 7 8 9 10 11 12 <h2 > Posts NEW</h2 > <%= form_for @post ,url: {action: "create" } do |f | %> <p > <%= f.text_field :title ,placeholder: 'placeholder1' %> </p > <p > <%= f.text_area :body ,placeholder: 'placeholder2' ,value: 'value' %> </p > <p > <%= f.submit 'POST' %> </p > <% end %>
url:{action:”[アクション名]”}のアクション名の部分に rails routes で確認できる Controller#Action の項目を割り当てる。 html への変換後に、URL Pattern に変換される。
ヘルパーから生成された html は以下のようになる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <h2 > Posts NEW</h2 > <form class ="new_post" id ="new_post" action ="/posts" accept-charset ="UTF-8" method ="post" > <input name ="utf8" type ="hidden" value ="✓ " /> <input type ="hidden" name ="authenticity_token" value ="/4V2EYdAOgyFi65+RjeHYww69LUC8dgkMsmn8jznXmEggGHLHNdbfhGe2xTZmONbZh85nNhLrQb+SbSEdUW2gw==" /> <p > <input placeholder ="placeholder1" type ="text" name ="post[title]" id ="post_title" /> </p > <p > <textarea placeholder ="placeholder2" name ="post[body]" id ="post_body" > value</textarea > </p > <p > <input type ="submit" name ="commit" value ="POST" data-disable-with ="POST" /> </p > </form >
フォームの入力を受け付ける [モデル名]_contriller.rb 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def create render plain: params[: [モデル名]].inspect puts params[: [モデル名]] @post = Post .new(params[: [モデル名]]) @post = Post .new(params.require (:post ).permit(:title ,:body )) @post .save redirect_to posts_path end
バリデーションを作る [アプリケーションルート]\app\models\モデル名.rb
1 2 3 4 class [モデル名] < ApplicationRecord validates :title ,presence: true ,length: {minimum: 5 ,message: 'SHORT!!' } validates :body ,presence: true end
presence は、空ではない項目つまり必須項目の指定。 length は文字列長の設定,上では minimum を使用して短さで指定しているが、 maximum(最大長),in(範囲),is(文字列長一致)などもある。
バリデーション結果で動作を振り分ける save メソッドが返り値を持っていて、 バリデーションの結果を errors.inspect に格納している。
[モデル名]_contriller.rb 1 2 3 4 5 6 7 8 9 10 def create @post = Post .new(params.require (:post ).permit(:title ,:body )) if @post .save redirect_to posts_path else render plain: @post .errors.inspect end end
バリデーションの結果がエラーのとき入力画面に返す場合 コントローラで、エラーのときに表示するビューを指定する。
[モデル名]_contriller.rb 1 2 3 4 5 6 7 8 9 def create @post = Post .new(params.require (:post ).permit(:title ,:body )) if @post .save redirect_to posts_path else render 'new' end end
ビューで、エラー時のみ表示する項目を設定する 各部分はどこでもよい。
1 2 3 4 5 6 <% if @post.errors.messages[:title].any? %> <span> <%= @post.errors.messages[:title][0] %> </span> <% end %>
これでエラー発生時に表示される項目が定義でできる。
また、エラーの対象になった項目 input タグが、field_with_errors クラスが付与された div 要素に包まれる。 標準の css だと赤が込みされた。
値の更新 コントローラで edit、update アクションを定義
[モデル名]_contriller.rb 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def edit @post = Post .find(params[:id ]) end def update @post = Post .find(params[:id ]) if @post .update(params.require (:post ).permit(:title ,:body )) render 'show' else render 'edit' end end
編集画面を edit.html.erb に定義 :title、:body のようにすることで、格納されたデータを value に埋め込む
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <h2>Posts EDIT</h2> <%= form_for @post ,url:{action:"update"} do|f|%> <p> <%= f.text_field :title,placeholder:'placeholder1' %> </p> <p> <%= f.text_area :body,placeholder:'placeholder2' %> <% if @post.errors.messages[:title].any? %> <span><% @post.errors.messages[:title][0] %></span> <% end %> </p> <p> <%= f.submit 'UPDATE' %> </p> <% end %>
以上でデータ更新画面の遷移が作成できた。
値の削除 コントローラで destroy アクションを定義
[モデル名]_contriller.rb 1 2 3 4 5 def destroy @post = Post .find(params[:id ]) @post .destroy redirect_to root_path end
どこかのビューで削除リンクを定義する。
1 <%= link_to 'DEL', method:delete post_path(post) data:{confirm:'DELETE OK?'}%>
edit 画面で現在の URL が/posts/6/edit のようなときボタンなら次のように作れた。
1 2 3 4 パターン1 <%= button_to "DELETE", post_path, {method: :delete} %> パターン2 <%= button_to "DELETE", {controller: 'posts', action: 'destroy'}, method: :delete %>
この時、<%= f.submit 'POST' %>
と共存しようとしたら、失敗した。 update と delete を共存する場合の edit のビューは次のようになった。<%= button_to 'UPDATE', {controller: 'posts', action: 'update'}, method: :patch %>
に書き換えて次のようにする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <h2>Posts EDIT</h2> <%= form_for @post ,url:{action:"update"}, method: :patch do|f|%> <p> <%= f.text_field :title,placeholder:'placeholder1' %> </p> <p> <%= f.text_area :body,placeholder:'placeholder2' %> <% if @post.errors.messages[:title].any? %> <span><% @post.errors.messages[:title][0] %></span> <% end %> </p> <p> <%= button_to 'UPDATE', {controller: 'posts', action: 'update'}, method: :patch %> <%= button_to "DELETE", {controller: 'posts', action: 'destroy'}, method: :delete %> </p> <% end %>
index 画面などであれば、それぞれの id を使用して次のようにできた。
1 2 3 4 5 <% @posts.each do|post|%> <li> <%= link_to post.title, post_path(post)%> <%= button_to "DELETE", post_path(post), method: :delete %> <% end %>
今回の記事ではデータの、CRUD(作成、読み出し、更新、削除)まで、できました。
長くなりすぎなので、続きは別記事にします。
以上