PROGRAMMING

Rubyフレームワークを用いたWebアプリケーションの開発方法(前半)

※今回はメモ的要素が強いです。

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=”○○”」が付いたフォームの入力内容を受け取る

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です