Open17

ruby on Rails学習録

m____hirokim____hiroki

bin/rails server -b 0.0.0.0 -p 3004
Railsの立ち上げコマンド
概念というか構造はMVCモデル

m____hirokim____hiroki

新規でやる場合はcontrollerを作成から始める
bin/rails generate controller Home index
これでcontrollerとviewが両方作成される

reactやnextならindexを作成したらパスは下記のようになるが
http://localhost:3004/home/
Railsはhttp://localhost:3004/home/indexになる

m____hirokim____hiroki

controllerで変数作成してその変数を紐づいているviewで表示できる

# controller
class HomeController < ApplicationController
  def index
    @message = "This is a test site of Ruby on Rails."
  end
end
# view
<h1>My Application</h1>
<%= @message %>

画面

m____hirokim____hiroki

リストをcontrollerで作成してviewで表示させる
リンクになっているからリストをクリックすると
http://localhost:3004/usersのようになる

# controller
class HomeController < ApplicationController
  def index
    @message = "This is a test site of Ruby on Rails"
    @links = [ "users", "books", "help" ]
  end
end
# view
<h1>My Application</h1>
<%= @message %>
<ul>
<% @links.each do |link| %>
  <li><a href="/<%= link %>"><%= link %></a></li>
<% end %>
</ul>

画面

m____hirokim____hiroki

同じcontroller内部に複数のcontrollerみたいなのを書ける
関数群みたいなもんよねdefだし

# controller
class HomeController < ApplicationController
  def index
    @message = "This is a test site of Ruby on Rails"
    @links = [ "users", "books", "help" ]
  end
  def help
    @message = "This is a test site of Ruby on Rails"
  end
end
# view help.html.erb
<h1>Help</h1>
<a href="/">Return</a>
<p>This is help page...</p>
<%= @message %>

画面

m____hirokim____hiroki

ルーティングの作成および修正
/config/routes.rb

Rails.application.routes.draw do
  root 'home#index' # パスが/ならこれを表示するというrootディレクトリ設定
  get 'home/index'
  get '/help', to: 'home#help' #フォルダ名/ファイル名
end
m____hirokim____hiroki

scaffoldの作成(足場)
bin/rails generate scaffold User name:string age:integer
bin/rails db:migrate
このコードで作成されるいやゆるscaffold(足場)は

  • DB:app/models/user.rbとして書き出される
  • controller:app/controllers/users_controller.rb
  • view:app/view/users/*
  • path:/users
    画面
m____hirokim____hiroki

DBを作成した際のデータの保存先、rootディレクトリでls dbで確認すると、
development.sqlite3 migrate schema.rb seeds.rbがあり、development.sqlite3にデータが保存される

development.sqlite3をコピーして他のプロジェクトに移せばデータをそのまま利用可能(Laravelみたい)

sqlite3 db/development.sqlite3のコマンドでSELECT * FROM users;を叩けば
テーブルの情報を取得することができる

m____hirokim____hiroki

コマンドでデータを作成する方法
scaffoldではないためマニュアルで作成していく認識

  • bookというDBを作成
    bin/rails generate model Book title:string author:string
    bin/rails db:migrate
  • データを作成するためのコマンド
    bin/rails console
    irb> book = Book.new(title: "吾輩は猫である", author: "夏目漱石")
    irb(main):002> book.save
    irb(main):002> book.all
    結果

ルーティングはuserを作成した時と同じ手順

m____hirokim____hiroki

booksの詳細画面を作成する

#controller
class BooksController < ApplicationController
  def index
    @books = Book.all
  end
# ここを追加
  def show
    @book = Book.find(params[:id])
  end
end
#view show.html.erb
<h1>Books</h1>
<a href="/books">Return</a>
<div>Title: <%= @book.title %></div>
<div>Author: <%= @book.author %></div>
# route
Rails.application.routes.draw do
  resources :users
  root 'home#index'
  get 'home/index'
  get '/help', to: 'home#help'
  get '/books', to: 'books#index'
# ここを追加
  get '/books/:id', to: 'books#show', as: :book
end

結果

m____hirokim____hiroki

先ほどコマンドで作成したbooksのデータをGUIで作成できるようにしてみる

#controller
class BooksController < ApplicationController
    def index
        @books = Book.all
    end
    def show
        @book = Book.find(params[:id])
    end
# ここを追加
    def new
        @book = Book.new
    end
end

indexページに新規作成用リンクを設置

#books/index
<h1>Books</h1>
<a href="/">Return</a>
<ul>
  <% @books.each do |book| %>
    <li><a href="/books/<%= book.id %>"><%= book.title %></a></li>
  <% end %>
# これでnewへのリンクを追加
  <%= link_to "Add", new_book_path %>
</ul>
#routes
Rails.application.routes.draw do
  resources :users
  root 'home#index'
  get 'home/index'
  get '/help', to: 'home#help'
# ここを追加(books/:idより先に書かないとidがないよとエラーが出る)
  get '/books/new', to: 'books#new', as: :new_book
  get '/books', to: 'books#index'
  get '/books/:id', to: 'books#show', as: :book
end

なぜ_pathが必要か

Railsのルーティング設定で名前付きルートを定義すると、以下のように自動的にヘルパーメソッドが生成されます
linkのnew_book_pathはroutesのnew_bookと紐づいていますが
new_book_pathの_pathの部分はヘルパーメソッドとして定義されhtmlとして
吐き出されるのは/books/newとなる

ちなみに_urlなら

new_book_urlだとすると吐き出されるのは絶対パスになります
例:http://localhost:3000/books/new

m____hirokim____hiroki

実際に作成する

#controller
class BooksController < ApplicationController
    def index
        @books = Book.all
    end
    def show
        @book = Book.find(params[:id])
    end
    def new
        @book = Book.new
    end
# ここを追加
    def create
        @book = Book.new(book_params)
        if @book.save
          redirect_to @book
        else
          render :new, status: :unprocessable_entity
        end
    end
    private
        def book_params
        params.require(:book).permit(:title, :author)
        end
end
# routes
Rails.application.routes.draw do
  resources :users
  root 'home#index'
  get 'home/index'
  get '/help', to: 'home#help'
  get '/books/new', to: 'books#new', as: :new_book
# ここを追加
  post '/books', to: 'books#create'
  get '/books', to: 'books#index'
  get '/books/:id', to: 'books#show', as: :book
end
# view books/new.html.erb
<h1>Books</h1>
<a href="/books">Return</a>
<%= form_with model: @book do |form| %>
  <div>
    <div><%= form.label :title %></div>
    <div><%= form.text_field :title %></div>
  </div>
  <div>
    <div><%= form.label :author %></div>
    <div><%= form.text_field :author %></div>
  </div>
  <div>
    <%= form.submit %>
  </div>
<% end %>

m____hirokim____hiroki

投稿までのデータの流れの整理
①フォームの送信

  • ここで作成したフォームがform_with model: @bookを設定してることによりpostで/booksに送信される
<%= form_with model: @book do |form| %>
  <div>
    <div><%= form.label :title %></div>
    <div><%= form.text_field :title %></div>
  </div>
  <div>
    <div><%= form.label :author %></div>
    <div><%= form.text_field :author %></div>
  </div>
  <div>
    <%= form.submit %>
  </div>
<% end %>

②フォームで飛ばされてきたデータをルーティングでコントローラに渡す

Rails.application.routes.draw do
  resources :users
  root 'home#index'
  get 'home/index'
  get '/help', to: 'home#help'
  get '/books/new', to: 'books#new', as: :new_book
  post '/books', to: 'books#create' # これ
  get '/books', to: 'books#index'
  get '/books/:id', to: 'books#show', as: :book
end

③飛んできたデータでデータを作成する

class BooksController < ApplicationController
    def index
        @books = Book.all
    end
    def show
        @book = Book.find(params[:id])
    end
    def new
        @book = Book.new
    end
    def create #これ
        @book = Book.new(book_params)
        if @book.save
          redirect_to @book
        else
          render :new, status: :unprocessable_entity
        end
    end
    private
        def book_params
        params.require(:book).permit(:title, :author)
        end
end

m____hirokim____hiroki

作成したbooksのデータを更新してみる

# contoroller
class BooksController < ApplicationController
    def index
        @books = Book.all
    end
    def show
        @book = Book.find(params[:id])
    end
    def new
        @book = Book.new
    end
    def create
        @book = Book.new(book_params)
        if @book.save
            redirect_to @book
        else
            render :new, status: :unprocessable_entity
        end
    end
#ここを追加
    def edit
        @book = Book.find(params[:id])
    end
#ここを追加
    def update
        @book = Book.find(params[:id])
        if @book.update(book_params)
            redirect_to @book
        else
            render :new, status: :unprocessable_entity
        end
    end
    private
        def book_params
        params.require(:book).permit(:title, :author)
        end
end
# view edit.html.erb
<h1>Books</h1>
<a href="/books">Return</a>
<%= form_with model: @book do |form| %>
  <div>
    <div><%= form.label :title %></div>
    <div><%= form.text_field :title %></div>
  </div>
  <div>
    <div><%= form.label :author %></div>
    <div><%= form.text_field :author %></div>
  </div>
  <div>
    <%= form.submit %>
  </div>
<% end %>
# view show.html.erb
<h1>Books</h1>
<a href="/books">Return</a>
<div>Title: <%= @book.title %></div>
<div>Author: <%= @book.author %></div>
# ここを追加
<%= button_to "Edit", edit_book_path, method: :get %>
# routes
Rails.application.routes.draw do
  resources :users
  root 'home#index'
  get 'home/index'
  get '/help', to: 'home#help'
  get '/books/new', to: 'books#new', as: :new_book
  post '/books', to: 'books#create'
  get '/books', to: 'books#index'
  get '/books/:id', to: 'books#show', as: :book
#ここを追加
  get 'books/:id/edit', to: 'books#edit', as: :edit_book
# ここで初めて出てきたpatch
  patch '/books/:id', to: 'books#update'
end

routesで使用するpatchとは?

post '/books', to: 'books#create'ここで使用しているようにformからpostのリクエストが来ればという条件のrouteなのでcreateになるとアルゴリズムは同じ

form_withは自動でpostまたはpatchを送信する仕組みなのでpostのrouteまたはpatchのrouteを通るから今回はpatchを通りcontrollerのupdateが呼び出される

m____hirokim____hiroki

railsでcredentialsのデータをちゃんと取得できているかの確認方法

rails console
irb(main):001:0 > Rails.application.credentials.blastengine[:envの名前]