LoginSignup
4
3

More than 5 years have passed since last update.

Ruby on Rails MVCの連携

Posted at

動作環境はMacです。

Ruby on Railsとは?

webアプリケーションを作るためのwebアプリケーションフレームワーク。
フレームワークとは、開発者が1から用意しなくても、必要なライブラリや、機能を自動で用意してくれるもの。

Rubyで書かれており、オープンソース(誰でも使用可能)

Railsと呼ばれたりR on Rと略されて呼ばれることもある。

作者 デイビット・ハイネマイヤー・ハンソン氏

歴史

2004年7月に最初のバージョンがリリース。

RailsのコンセプトはPHPフレームワークのcakePHPやSymfonyになどに影響を与えている。

Ruby Gems

  • gemというライブラリの形式が採用。
  • よく使う機能がgemで公開されているので、開発工数を削減できる。
  • RubyGemsはライブラリの作成やインストールを助けるシステム。

Railsプロジェクトの作成

ターミナル

$ cd ~/フォルダ名/ #任意のフォルダへ移動
$ cd rails_projects  #ここではrails_projectsというフォルダを作成し移動
$ rails _5.2.2_new hello #rails projectsの新規作成コマンド ここではバージョンを指定している

rails newコマンドでアプリケーション作成に必要なフォルダを自動的に生成してくれる。


動作確認

下記コマンドでrailsの動作確認が可能

$rails s #railsサーバーの立ち上げ

railsはwebサーバーを持っており、web上で閲覧が可能になる。
rails sを起動し、割り当てられらURLにアクセスすると、welcome画面が表示される。
URLを知っていれば第三者から閲覧が可能になる。

$rails c #railsサーバーの終了

上記コマンドでURLにアクセスしてもwelcome画面が表示されなくなる。

コントローラーの作成

ブラウザに表示するには、最低でもコントローラーが必要になる。

$ rails g controller users index

rails g controllerで必要なコントローラーのファイル群を作成。
コントローラー名は複数形が基本。(データベースに紐づかない場合は単数形になる場合も)
indexはコントローラーに記述されるアクション(メソッド)。

users_controller.rb

class UsersController < ApplicationController #Userscontrollerはappricationコントローラーを継承している。
  def index #これがアクション(メソッドと同義)
    render plain: "Hello!,World!" #renderはブラウザに表示 plainは平語のテキストの意味
  end
end

これでブラウザ上に表示されるようになる。

ルーティング

URLとマッチするアクションに振り分けるための機能

下記コマンドでURLとコントローラー、アクションの結びつきを確認することが可能。

$rails routes
                   Prefix Verb URI Pattern                                                                              Controller#Action
              users_index GET  /users/index(.:format)                                                                   users#index
       rails_service_blob GET  /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
rails_blob_representation GET  /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
       rails_disk_service GET  /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
update_rails_disk_service PUT  /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
     rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create

prefixはパスの指定で使用可能。
VerbはHTTPメソッドのこと。GETはデータ取得 POSTはデータ送信 DELETEはデータ削除など。
URI Pattern はざっくりURLと同義。
Controller#Actionはコントーラーのどのアクションと結びついているかを示すもの

現在下記の通りURLにusers/indexが指定された時にコントローラーのindexアクションが呼ばれる仕様になっている。

routes.rb

Rails.application.routes.draw do
   #get 'users/index'
    get 'users/index', to: "users#index" #上の記述と同じ意味。
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

これをusers/のURLが指定された時にindexアクションがよばれるように書き換えてみる。

routes.rb

Rails.application.routes.draw do
  #get 'users/index'
  get 'users/', to: "users#index"  #users/indexからusers/に書き換え

  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

上記に書き換えるとusers/のURL指定でUsersコントローラーのindexアクションが呼ばれる。users/indexに指定すると、Routing Errorrとなる。

routesで確認してみる。

rails routes
                   Prefix Verb URI Pattern                                                                              Controller#Action
                    users GET  /users(.:format)                                                                         users#index 
       rails_service_blob GET  /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
rails_blob_representation GET  /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
       rails_disk_service GET  /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
update_rails_disk_service PUT  /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
     rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create

viewの作成

現在、コントローラーのみをしようして、画面にレンダリング(描写)しているが、RailsのMVC思想に基づくと不自然なので、viewを作成しそこに記述を指定していく。

users.controller.rb


class UsersController < ApplicationController
  def index
    #render plain: "Hello!,World!"
  end
end

上のコントローラのindexアクションにひもづくviewはrails gコマンドの時に自動的に作成されているので、開発者が指定する必要はない。
app/views/controller/index.htmlに記述する
app/views/コントローラー名/アクション名.html.erb

自動的に生成されている。

index.html.erb
<p> Hello! World.</p>

このファイルへの記述でUsersコントローラーのindexアクションと紐付くviewがレンダリングされる。

ERB

viewにrubyの機能を埋め込む技術

index.html.erb
<p> Hello! World.</p>
<p>
  <%= 10 + 1 %> #<%= %>の内側がrubyのプログラム
</p>

<%= %>はレンダリングをしたい時の記述
<% %>とイコールを外すと、レンダリングされない
if文など表示する必要がない場合は=は外す。

ControllerからViewに値を渡す

Viewへの記述はなるべくレンダリング作業のみにしたいので、プログラミムの処理などはControllerやModelなどに記述するようにする。

users_controller.rb

class UsersController < ApplicationController
  def index
    #render plain: "Hello!,World!"
  @num = 10 + 1 #viewのプログラムをControllerに記述
  end
end
index.html.erb
<p> Hello! World.</p>
<p>
  <%= 10 + 1 %>
</p>

<p>
  <%= @num %> #viewへは渡されたインスタンス変数を記述
</p>

ローカル変数numとした場合はviewへの描写はできないので注意。

Modelの作成

コマンド

$rails g model モデル名 カラム名:データ型

主なデータ型
integer 整数
float 小数点
string 文字列
text 長い文字列
boolean 真偽値

どのデータベース製品でも適用できる。

userモデルを作成

$ rails g model user name:string age:integer

上記コマンドで必要なファイル群が作成される。

/db/migrateフォルダの中に、migrateファイルが作成されている。
これは、テーブルの構造の変更をする際に必要なファイル。

timestamp_create_users.rb

class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :name
      t.integer :age

      t.timestamps #自動で作成される。レコードの作成や、編集の日付を管理するカラム
    end
  end
end

ターミナルで下記のコマンドを実行しmigrateを実行

rails db:migrate
== 20190306031934 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0020s
== 20190306031934 CreateUsers: migrated (0.0021s) =====================

データベース構造の確認

下記コマンドでデータベースをコマンドで確認することができるようになる。

$rails dbconsole
sqlite> .tables #テーブルを確認
ar_internal_metadata  schema_migrations     users               
sqlite> .schema users #usersテーブルの中身の確認
CREATE TABLE IF NOT EXISTS "users" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "age" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL); #migrateファイルに記述したtimestampがcreated_atと  updated_atのカラムを自動的に生成してくれている。

標準ではsqliteと呼ばれる軽量のデータを扱う製品が用意されている。mysqlなどの他のデータベース製品をしようすることもできる。

.quitか.qで抜ける。

データベースの操作

下記のコマンドでデータベースの操作をすることが可能
rubyでいうirbみたいなもの。

$rails c #consoleの略

irb(main):002:0> User.all  #Userテーブルのデータを取得
  User Load (0.7ms)  SELECT  "users".* FROM "users" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
irb(main):003:0> user = User.new #Userクラスのインスタンスを作成
=> #<User id: nil, name: nil, age: nil, created_at: nil, updated_at: nil>
irb(main):004:0> user.name = "Kiyosiro Imawano" #インスタンスに名前を代入
=> "Kiyosiro Imawano"
irb(main):005:0> user.age = 40 #インスタンスに年齢を代入
=> 40
irb(main):006:0> user.save #テーブルにデータを保存
   (0.1ms)  begin transaction
  User Create (0.6ms)  INSERT INTO "users" ("name", "age", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "Kiyosiro Imawano"], ["age", 40], ["created_at", "2019-03-06 03:58:57.264789"], ["updated_at", "2019-03-06 03:58:57.264789"]]
   (7.0ms)  commit transaction
=> true
irb(main):007:0> User.all #Userテーブルのデータを取得
  User Load (0.2ms)  SELECT  "users".* FROM "users" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 1, name: "Kiyosiro Imawano", age: 40, created_at: "2019-03-06 03:58:57", updated_at: "2019-03-06 03:58:57">]>

IDのデータを取得


irb(main):013:0> User.find(1)
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "Kiyosiro Imawano", age: 40, created_at: "2019-03-06 03:58:57", updated_at: "2019-03-06 03:58:57">

データの更新 
IDが1のデータを書き換える。

  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "Kiyosiro Imawano", age: 40, created_at: "2019-03-06 03:58:57", updated_at: "2019-03-06 03:58:57">
irb(main):020:0> user.name = "Kensiro Kaneko"
=> "Kensiro Kaneko"
irb(main):021:0> user.age = 23
=> 23
irb(main):022:0> user.save
   (0.1ms)  begin transaction
  User Update (0.5ms)  UPDATE "users" SET "name" = ?, "age" = ?, "updated_at" = ? WHERE "users"."id" = ?  [["name", "Kensiro Kaneko"], ["age", 23], ["updated_at", "2019-03-06 04:11:34.304540"], ["id", 1]]
   (6.8ms)  commit transaction
=> true
irb(main):023:0> User.all
  User Load (0.2ms)  SELECT  "users".* FROM "users" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 1, name: "Kensiro Kaneko", age: 23, created_at: "2019-03-06 03:58:57", updated_at: "2019-03-06 04:11:34">, #<User id: 2, name: "21", age: nil, created_at: "2019-03-06 04:02:37", updated_at: "2019-03-06 04:02:37">]>

#書き換わった!!

Userテーブルのデータを削除



irb(main):030:0> User.all             
  User Load (5.3ms)  SELECT  "users".* FROM "users" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 2, name: "21", age: nil, created_at: "2019-03-06 04:02:37", updated_at: "2019-03-06 04:02:37">]>
irb(main):031:0> user = User.find(2) 
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
=> #<User id: 2, name: "21", age: nil, created_at: "2019-03-06 04:02:37", updated_at: "2019-03-06 04:02:37">
irb(main):032:0> user.destroy 
   (0.6ms)  begin transaction
  User Destroy (0.4ms)  DELETE FROM "users" WHERE "users"."id" = ?  [["id", 2]]
   (1.0ms)  commit transaction
=> #<User id: 2, name: "21", age: nil, created_at: "2019-03-06 04:02:37", updated_at: "2019-03-06 04:02:37">
irb(main):033:0> User.all
  User Load (0.2ms)  SELECT  "users".* FROM "users" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>

ロードと削除を一緒に行うには
User.find(id).destroyとする。

Webページにデータを反映させる

データベースの作成


irb(main):051:0> sato = User.new(name: "Aki Sato", age: 25)
=> #<User id: nil, name: "Aki Sato", age: 25, created_at: nil, updated_at: nil>
irb(main):052:0> sato.save
   (0.1ms)  begin transaction
  User Create (1.0ms)  INSERT INTO "users" ("name", "age", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "Aki Sato"], ["age", 25], ["created_at", "2019-03-06 12:48:00.277643"], ["updated_at", "2019-03-06 12:48:00.277643"]]
   (6.6ms)  commit transaction
=> true
irb(main):053:0> kaneki = User.new(name: "Ken Kaneki", age: 32)
=> #<User id: nil, name: "Ken Kaneki", age: 32, created_at: nil, updated_at: nil>
irb(main):054:0> kaneki.save
   (0.1ms)  begin transaction
  User Create (1.1ms)  INSERT INTO "users" ("name", "age", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "Ken Kaneki"], ["age", 32], ["created_at", "2019-03-06 12:48:55.171055"], ["updated_at", "2019-03-06 12:48:55.171055"]]
   (6.5ms)  commit transaction
irb(main):004:0> imawano = User.new(name: "Kiyosiro Imawano", age: 50)
=> #<User id: nil, name: "Kiyosiro Imawano", age: 50, created_at: nil, updated_at: nil>
irb(main):005:0> imawano.save
   (0.1ms)  begin transaction
  User Create (0.8ms)  INSERT INTO "users" ("name", "age", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "Kiyosiro Imawano"], ["age", 50], ["created_at", "2019-03-06 12:58:05.599302"], ["updated_at", "2019-03-06 12:58:05.599302"]]
   (6.3ms)  commit transaction
=> true
irb(main):006:0> User.all
  User Load (1.0ms)  SELECT  "users".* FROM "users" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 4, name: "Aki Sato", age: 25, created_at: "2019-03-06 12:48:00", updated_at: "2019-03-06 12:48:00">, #<User id: 5, name: "Ken Kaneki", age: 32, created_at: "2019-03-06 12:48:55", updated_at: "2019-03-06 12:48:55">, #<User
users_controller.rb

class UsersController < ApplicationController
  def index
    #render plain: "Hello!,World!"
  @num = 10 + 1
  @users = User.all #作成したデータをインスタンス変数に代入

  end
end
index.html.erb

<p> Hello! World.</p>
<p>
  <%= 10 + 1 %>
</p>

<p>
  <%= @num %>
</p>

<ul>
  <% @users.each do |user| %>
    <li> <%= user.id%>, <%= user.name%>, <%= user.age %> </li>
  <% end %>
#この記述で、ブラウザにデータベースの内容を反映させることができる。
</ul>
4
3
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
4
3