※今回はメモ的要素が強いです。
Ruby on Rails は、 Rubyを使用してWeb アプリケーションを構築するフレームワークです。
本フレームワークは、アプリケーション内部の処理内容に基づいて、3つの役割を担うモデル(M)、ビュー(V)、コントローラー(C)から構成されるMVCモデルをフレームワークの基礎にしています。
フレームワークの構成については、下記サイトがイメージしやすかったので、リンクを貼っておきます。
https://codezine.jp/article/detail/11574
マスターすれば、自由自在に好きな Web アプリケーションを創れるようになります。CockpadやAirbnbなどもこのフレームワークを使用して作成されています。
アプリケーションの準備
①アプリケーション名を決め、ターミナル1にコマンド:「rails new “アプリケーション名“」 を打ち込み、必要なフォルダやファイルを作成する。
②ターミナル2にコマンド:「rails server」を打ち込み、サーバーを起動する。
※rails serverは起動し続けておく必要があるので、これ以降「ターミナル2」を触る必要はなく、今後必要なコマンドは「ターミナル1」に入力する。
③ブラウザに”localhost:3000”を打ち込み、サーバーを立ち上げ、画面が表示されたらOKです。
トップページの作成
①コマンド:「rails generate controller home top」をターミナル1で実行しますう。これで「localhost:3000/home/top」というURLにアクセスできるようになります。
※このコマンドは、controller名:home, アクション名:top です。
このコマンドにより、ページを表示するために必要な3つのファイル(view,controller,routing)を作成できます。
②app/views/home/のtop.html.erb及びapp/assets/stylesheet/のhome.scssを編集します。
view
ビューとは、ページの「見た目」を作るためのHTMLファイルです。
ブラウザとRailsのやりとりの中で、Railsからビューが返され、ページが表示されます。
controller
View(htmlファイル)をブラウザに返します。
「rails g controller home top」を実行したとき、「home_controller.rb」というコントローラのファイルが作成され、「topメソッド(def top ~ end)」が追加されます。
コントローラ内のメソッドを「アクション」と呼びます。「def ○○ ~ end」がアクションです。
ページを表示するとき、Railsの中ではコントローラを経由してビューをブラウザに返しますが、コントローラ内のアクションは、ブラウザに返すビューをviewsフォルダの中から見つけ出す役割を担っています。
例えば、home_controllerのtop アクション(def top ~ end)に対応するtop.htmlファイル(viewsフォルダ内)を探して、ブラウザに返します。
routing
ブラウザとcontroller(rails内)の間で働き、ブラウザから送信されたURLに対して「どのコントローラの、どのアクション」で処理するかを選択・決定します。
ルーティングは「config/routes.rb」ファイルに定義され、「get “URL” => “コントローラー名#アクション名”」で記載する。
- 上記の”URL”を書き換えるとURLを変更できます (“/” とか”home/top”とか)
- ”コントローラー名#アクション名”は特に変更しなくていい?かな
これにより、例えば、ブラウザから「localhost:3000/home/top」というURLが送信されたときに、homeコントローラーのtopアクションで処理されるようになります。
Routingに記載のないURLが来た場合、処理は不可能 → エラーになります。
アプリケーション紹介ページの追加・作成
①すでに作られているroutingとcontrollerのファイルにコードを書き足すことで、ルーティングとアクションを追加します。
・routes.rbでは
get “about” => “home#about” (紹介ページURLを”about”に設定)
・home_controller.rbでは
def about
end
※トップページ作成時に使用したコマンド:「rails generate controller home about」は使用できません。理由は、同じ名前のコントローラ(”home”)がすでにある場合は、このコマンドを使うことはできないからです。
②紹介ページのhtmlファイルを手動で作成し、そのファイルを編集します。
apps/views/homeで右クリックして新規ファイルを自分で作成(about.html.erb)(erb = embedded rubyの略称)
※この時、トップページと紹介ページに同じhtmlを適用したい場合は、views/layouts/application.html.erb に記載すれば、記載内容が共有されます。
③home.scssでレイアウトを編集します。
画像の追加
画像は、「public」フォルダに配置しておくと、「<img src=”/画像名” >」や「background-image: url(“/画像名”);」のように、画像名を指定するだけで、簡単に画像を表示することができます。
リンクの作成
例えば、トップページと紹介ページのヘッダー部分の文字をリンクに変更するにはapplication.html.erbにheader(これはbody内部に)を記載します。
リンクにしたいところを link_toメソッドを用いる → <%= link_to(“リンクタイトル”, “URL”) %>
例えば
<%= link_to “Yahooへ移動する”, “http://www.yahoo.co.jp/” %>
htmlの<a>タグと同じ → <a href=“URL”>リンクタイトル</a>
投稿機能の作成
①postsコントローラを作成します。
ターミナル1でコマンド:「rails g controller posts index」を打ち込む→routes.erbファイルに、get “posts/index” => “posts#index”が追加されます。
posts_controller.rbに、index(def index ~ end)アクションを持ったpostsコントローラが作成されています。
一覧ページを作成する時は、indexというアクション名を使用することが一般的のため使用します。
※home コントローラでも作成することはできますが、投稿に関することは、投稿に関するコントローラを作成した方が良いです。
②htmlのままではデータベースと接続できないため、投稿内容(html)を変数に代入し表示させます。
この時、index.html.erbのようなerb形式ファイルでは、<% %>で囲むことで、HTMLファイルの中にRubyのコードを記述することができます。
また、埋め込むRubyコードをブラウザに表示したい場合には、<%= %>を用います。
さらに、変数をビューファイル内で定義する際、Rails ではビューではなく、アクション(controller内)で定義することが一般的です。
通常、アクション(def ○○ ~ end)で定義した変数をviewで使用することはできませんが、変数名を「@」から始めることで、viewファイルでもcontrollerのアクションでも両方で使用することができます。
つまり
❶ <% @post1 = “~~~~~” %> (これで定義して)
❷ <%= @post1 %> (これで”~~~~~”がブラウザに表示される)
この時、投稿数が増えるたびにhtml記載が煩雑になります。これを回避するためにeach文で表示させた方が良いです。(投稿内容は全て取り出す設定)
つまり
❶ @posts = Post.all
❷ <% @posts.each do |post| %>
<div>
<%= post.content %>
</div>
<% end %>
コードのファイル内の記載場所に関して、
・controllerファイルでは
❶はアクションで定義(def index ~ end内)
❷は記載不要(viewファイルに記載)
・viewファイルでは
❶は記載不要(アクションで定義しているから)
❷はブラウザに表示されるため、実際にページ内に表示したいところに。
データベースの作成
データベースとは
データを保存しておく場所のことです。
データベースの仕組み
表(「テーブル」と呼ばれる)でデータを管理しています。
縦の列は「カラム」、横の行は「レコード」と呼びます。
横の行がデータの一つ一つとなっている。
①テーブルを作成します。
まずは、マイグレーションファイルと呼ばれる、データベースに変更を指示するためのファイルを作成します。
マイグレーションファイルはコマンド:「rails g model Post content:text」でターミナル1にて作成することができます。
※このコマンドは、モデル名:Post, カラム名:content, カラムへのデータの入り方(データ型):text です。
同時に、posts テーブルを操作するための Postモデルがすでに生成されています(app/modelsフォルダの中のpost.rb)
②データベースに変更を反映させます。
ターミナル1にてコマンド:「rails db:migrate」を実行すると、contentカラムを持ったpostsテーブルが作成されます。
テーブルへの投稿データ保存〜データ取り出しとビュー表示
①ターミナル1にてコマンド:「rails console」を打ち込みます。
ついで、PostモデルからPostインスタンスを作成します。
インスタンスを作成するにはnewメソッドを使います。
こんな感じ
rails console
>post = Post.new(content:”内容”)
※このコマンドは、モデル名:Post, メソッド名:new, カラム名:content です。
②上記で作成したPostインスタンスをPostsテーブルにsaveメソッドを用いて保存します。
> post.save
定義した変数は「quit」でconsole終了させるまで使い続けることができます。
③データを取り出して、ビューで表示します。(4−2で表示は設定済)
方法❶ postsテーブルからひとつのデータ(投稿内容(content))を取り出す
rails console
>post = Post.first
>post.content
>quit
もしくは
rails console
>post = Post.find_by(id:3)
>post.content
>quit
find_by メソッド
あるカラムを使ってレコードを検索し、最初に一致したものを返します。
例えば、nameカラムが「Kenzo」であるレコードを1つ取り出します。
引数には、(name: “Kenzo”)のようにハッシュで「カラム名: 値」を指定します。
方法❷ postsテーブルからすべてのデータ(投稿内容(content))を取り出す
rails console
>posts = Post.all
>Post.all[id番号]
>Post.all[id番号].content
>quit
投稿詳細ページの作成
①新規ページを作成します。 (routeとcontrollerは4−1で作成したものを使用)
・routes.rbでは
get “posts/:id” => “posts#show”
※routingは合致するURLを上から順に探すため、記載順に注意。「posts/:id」と書くと「/posts/◯◯」のような全てのURLが該当します。
・posts_controller.rbでは
def show
@post = Post.find_by(id: params[:id]) (→ idカラムがparams[:id]である投稿データを取得している)
end
・viewファイルは新規で作成します。(e.g show.html.erb)
<div>
<%= @post.content %>
<div>
<%= @post.created_at %>
</div>
</div>
②投稿一覧ページの投稿をクリックした時に、クリックした投稿の詳細ページに移動させます。
”投稿機能の作成”の②を編集して
<% @posts.each do |post| %>
<div>
<%= link_to(@post.content, ”/posts/#{post.id}” %> (黒字は変数展開)
</div>
<% end %>
※”投稿機能の作成”の②で記載した<%= post.content %>は削除
変数 params
コントローラのアクション内では、ルーティングで設定したURLの「:id」の値を取得することができます。
その値はparamsという変数にハッシュとして入っています。params[:id]とすることで、その値を取得することができます。
新規投稿ページの作成
①URL:/posts/newでアクセスできるようにするため、新規ページを作成します。
・routes.rbでは
get “posts/new” => “posts#new”
※これまでの順番は、posts/index > posts/new > posts/show > posts/:id > / > about
・posts_controller.rbでは
def new
end
・viewファイルは新規で作成する(e.g new.html.erb)
<div class=”main posts-new”>
<div class=”container”>
<h1 class=”form-heading”>投稿する</h1>
<div class=”form”>
<div class=”form-body”>
<textarea></textarea>
<input type=”submit” value=”投稿”>
</div>
</div>
</div>
</div>
②ヘッダーにリンクを作成します。
共通ファイルpplication.html.erbに
<%= link_to(“新規投稿”,”/posts/new”) %>
③投稿フォームの投稿を受け取り・保存していくために、まずrouteを設定します。
routeでは、フォームの値を受け取る際に、postを使用します。
post “URL” => “”コントローラー名#アクション名”
フォームの投稿ボタンを押すと、Rails側に投稿データが送信されます。
今回はcreateアクションを用意して、受け取った投稿データをデータベースに保存します。createアクションURLは「/posts/create」です。
④投稿フォームで投稿した内容をリダイレクトを用いて、他のURL(今回は投稿一覧ページURL “/posts/index”)に転送します。
posts_controller.erbで
def create
redirect_to(“/posts/index”)
end
⑤変数 paramsを用いて投稿内容を保存します。
先ほどのposts_controller.erbに追記で
def create
@post = Post.new(content: params[:content])
@post.save
redirect_to(“/posts/index”)
end
⑥viewファイルでは、form_tagメソッドを使用します。
このメソッドではフォームに入力されたデータを送信することができます。
form_tagは、「form_tag(送信先のURL) do」のように送信先のURLを指定します。
これによって、<input type=”submit” …>のボタンを押した時に、指定されたURLにデータが送信されます。
また、今の状態のフォームでは、投稿ボタンを押しても入力した内容をcreateアクションに伝えることができません。
そのため、<textarea>タグにname属性を指定します。
そうすると、入力データを送信することができるようになり、name属性の値をキーとしたハッシュがRails側に送られます。
<%= form_tag(“/posts/create”) do %>
<div class=”form”>
<div class=”form-body”>
<textarea name=“content”></textarea>
<input type=”submit” value=”投稿”>
</div>
</div>
<% end %>
⑦投稿を並び替えます。
orderメソッドを用いることで、投稿一覧を並び替えることができます。
order(カラム名: 並び替えの順序)のように使います。
並び替えの順序には、昇順(:asc)と降順(:desc)のどちらかを指定できます。
created_atを基準に降順(:desc)に並べ替えると、新しいものから順番に表示するようにできる。
例えば、
def index
@posts = Post.all.order(created_at: :desc
end
※上記のようにする場合は、重複を避けるためindexアクション内にある@posts = Post.all は削除する。
form_tagメソッドの注意点
- <%= %>で囲む
- doとendの中にフォームを書く
変数 params まとめ
- 「:○○」を使ったルーティングのURLから値を取得する get /posts/:○○ => ..
- 「name=”○○”」が付いたフォームの入力内容を受け取る