ruby on Rails学習録
![m____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
rails new myapp
でRailsのプロジェクトを作成
![m____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
bin/rails server -b 0.0.0.0 -p 3004
Railsの立ち上げコマンド
概念というか構造はMVCモデル
![m____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
新規でやる場合はcontrollerを作成から始める
bin/rails generate controller Home index
これでcontrollerとviewが両方作成される
reactやnextならindexを作成したらパスは下記のようになるが
http://localhost:3004/home/
Railsはhttp://localhost:3004/home/index
になる
![m____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
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____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
リストを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____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
同じ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____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
ルーティングの作成および修正
/config/routes.rb
Rails.application.routes.draw do
root 'home#index' # パスが/ならこれを表示するというrootディレクトリ設定
get 'home/index'
get '/help', to: 'home#help' #フォルダ名/ファイル名
end
![m____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
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____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
DBを作成した際のデータの保存先、rootディレクトリでls db
で確認すると、
development.sqlite3 migrate schema.rb seeds.rb
があり、development.sqlite3
にデータが保存される
development.sqlite3
をコピーして他のプロジェクトに移せばデータをそのまま利用可能(Laravelみたい)
sqlite3 db/development.sqlite3
のコマンドでSELECT * FROM users;
を叩けば
テーブルの情報を取得することができる
![m____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
コマンドでデータを作成する方法
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____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
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____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
先ほどコマンドで作成した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____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
実際に作成する
#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____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
投稿までのデータの流れの整理
①フォームの送信
- ここで作成したフォームが
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____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
作成した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____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
大体理解できてきたから一旦終了
![m____hiroki](https://res.cloudinary.com/zenn/image/fetch/s--bEzGUh9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/7a3c5a429a.jpeg)
railsでcredentialsのデータをちゃんと取得できているかの確認方法
rails console
irb(main):001:0 > Rails.application.credentials.blastengine[:envの名前]