0
1

More than 1 year has passed since last update.

Rails

Posted at

前置

各役割や書き方などをまとめてみました
サンプルコード→解説という形式です
コードはコピペでくっつけたものなので、意味としてはぐちゃぐちゃです
こんな感じで書くんだーって程度に見てください

コントローラ

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で各カラムに対して制限をかける。正規表現も使える
0
1
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
0
1