前置
各役割や書き方などをまとめてみました
サンプルコード→解説という形式です
コードはコピペでくっつけたものなので、意味としてはぐちゃぐちゃです
こんな感じで書くんだーって程度に見てください
コントローラ
rails g controller Users new
rails g controller コントローラ名 アクション名
- コントローラ名は、頭大文字、複数形
- コントローラファイルとビューフォルダとアクションが生成
app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :logged_in_user
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
redirect_to users_path
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name,:password,
:password_confirmation)
end
def logged_in_user
unless logged_in?
flash[:danger] = "ログインしてください"
redirect_to login_url
end
end
end
-
before_action メソッド名
で、各アクションを行う前に処理を行える -
before_action メソッド名, only: [:アクション名,:アクション名]
で、指定したアクションのみに適用される - コントローラは全て
ApplicationController
を継承しているので、全コントローラで行いたいメソッドはApplicationControllerに記述する - 不正な操作を防ぐため、送られてきたリクエストから必要な値だけを取得するメソッドを定義する
ルーティング
config/routes.rb
root 'static_pages#home'
get '/contact', to: 'static_pages#contact'
get '/date/:date' to: 'static_pages#date'
resources :users, only[:new, :create, :show]
-
root 'コントローラ名#アクション名'
で、ルートパスでどのアクションを行うか指定する -
httpリクエスト 'パス', to: 'コントローラ名#アクション名'
で、そのパスに送られてきたリクエストに対して、どのアクションを返すのか指定 - パスの中の
:OO
は指定したコントローラで呼び出せる -
resources :コントローラ名
で、そのコントローラに対して決められたアクションとパスが用意される。一覧は下記 -
only[:アクション名]
で、使用するアクションを制限できる
HTTPリクエスト | URL | アクション | 名前付きルート | 用途 |
---|---|---|---|---|
GET | /users | index | users_path すべてのユーザーを一覧するページ | |
GET | /users/1 | show | user_path(user) | 特定のユーザーを表示するページ |
GET | /users/new | new | new_user_path | ユーザーを新規作成するページ(ユーザー登録) |
POST | /users | create | users_path | ユーザーを作成するアクション |
GET | /users/1/edit | edit | edit_user_path(user) | id=1のユーザーを編集するページ |
PATCH | /users/1 | update | user_path(user) | ユーザーを更新するアクション |
DELETE | /users/1 | destroy | user_path(user) | ユーザーを削除するアクション |
ビュー
app/views/layouts/application.html.rb
<!DOCTYPE html>
<html lang="ja">
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title><%= yield(:title) %></title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
</script>
<![endif]-->
</head>
<body>
<header class="navbar sticky-top bg-black">
<div class="container d-flex justify-content-between">
<div class="h1 text-light">
MYAPP
</div>
<% if logged_in? %>
<%= link_to "ログアウト", logout_path,
method: :delete, class: "btn btn-outline-danger" %>
<% end %>
</div>
</div>
</header>
<main>
<%= yield %>
<%= debug(params) if Rails.env.development? %>
</main>
</body>
</html>
- どのページにも適用される要素は
layouts/application.html.rb
に記述 - getリクエストを受けた場合、
app/views/コントローラ名/アクション名.html.rb
が表示される - if文で、条件に合わせて要素を変更することも可能
<% provide(:title, "新規登録") %>
<div class="container">
<div class="row justify-content-center py-5">
<div class="col-md-6 col-md-offset-3 p-4 bg-white">
<h1 class="text-center mb-3">新規登録</h1>
<%= form_with(model: @user, local: true) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name, "名前" %>
<%= f.text_field :name, class: "form-control" %>
<%= f.label :password, "パスワード" %>
<%= f.password_field :password, class: "form-control" %>
<%= f.label :password_confirmation, "パスワードを確認" %>
<%= f.password_field :password_confirmation, class: "form-control" %>
<%= f.submit "ユーザを作成", class: "btn btn-primary w-100 mt-3" %>
<% end %>
</div>
</div>
</div>
-
<% provide(:キー, 値) %>
と指定しておけば、layouts/application.html.rb
で<%= yield(:キー) %>
で呼び出せる - form_withでフォームの作成
-
model: @user
インスタンス変数はコントローラで定義したもの。渡されたオブジェクトによってPOSTかPATCHか自動で判断される
モデル・マイグレーション
新しいモデルの作成
rails g model User name:string
-
rails g model モデル名 カラム名:カラムの型
で、モデルに必要なファイルが生成される
db/migrate/[timestamp]_create_users.rb
class CreateArticles < ActiveRecord::Migration[5.2]
def change
create_table :users do |t|
t.string :name
t.timestamps
end
end
end
- create_tableによって新しいテーブルが作られる
- 一意性を持たせたい場合はchangeメソッド内のcreate_tableブロック外に
add_index :テーブル名, :カラム名,unique: true
rails db:migrate
- 変更したものを反映させるために使うコマンド
既存モデルにカラムの追加
rails g migration add_password_digest_to_users password_digest:string
- カラムを追加したい場合のコマンド
rails g migration マイグレーションファイル名 カラム名:カラムの型
db/migrate/[timestamp]_add_password_digest_to_users.rb
class AddPasswordDigestToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :password_digest, :string
end
end
add_column :テーブル名, :カラム名, :データ型
rails db:migrate
- 変更したものを反映させるために使うコマンド
子モデルの作成
rails g model Micropost content:text user:references
- 最後に
モデル名:references
をつけることで、関連付けをさせる
db/migrate/[timestamp]_create_microposts.rb
class CreateMicroposts < ActiveRecord::Migration[6.0]
def change
create_table :microposts do |t|
t.text :content
t.references :user, foreign_key: true
t.timestamps
end
add_index :microposts, [:user_id, :created_at]
end
end
-
t.references :user, foreign_key: true
によって、user_idを外部キーとして持たせる -
add_index :microposts, [:user_id, :created_at]
複数のキーを配列として渡すことで、複合キーインデックスを作成
モデルファイル
app/models/user.rb
class User < ApplicationRecord
has_many :microposts, dependent: :destroy
default_scope -> { order(id: :asc) }
VALID_NUMBER_REGEX = /\A[0-9][0-9][0-9][0-9]\z/
validates :number, presence: true, length: { is: 4 },
format: {with: VALID_NUMBER_REGEX},
uniqueness: true
end
-
has_many :子モデル
で 1対多 の関連付け - 子モデル側には
belongs_to :親モデル
を記述 -
dependent: :destroy
で、親が削除されれば、関連された子データも全て削除される - default_scopeでデータの並び替え
- validatesで各カラムに対して制限をかける。正規表現も使える