Progateで学習した基本的なコマンド等をおさらいしました。
ここでは、投稿機能の実装をしています。
ここでは、投稿機能の実装をしています。
Ruby on Rails5 学習コースⅠ
・Railsアプリケーションの作成
$ rails new tweet_app # Railsアプリケーションの作成
$ rails server # サーバ起動
$ rails g controller home top # homeコントローラの作成
# 上記コマンドで下記3つのファイルが作成される
tweet_app/config/routes.rb # routing設定ファイル
tweet_app/app/controllers/home_controller.rb # controllerファイル
tweet_app/app/views/home/top.html.erb # viewファイル
tweet_app/app/assets/stylesheets/home.scss # CSSファイル
# 画像は下記ディレクトリ配下に格納する
tweet_app/public/
# 記述方法
# viewファイル(views/home/about.html.erb)
<img src="/tweets.png">
# CSSファイル(assets/stylesheets/home.scss)
background-image: url("/top.jpg");
・コントローラの削除
$ rails destroy controller home # 誤って作成した場合、このコマンドで削除できる
・完成版
# (routes.rb) get "/" => "home#top" get "about" => "home#about" # (home_controller.rb) def top end def about end
Ruby on Rails5 学習コースⅡ
変数の定義: erbという形式のファイルで、<% %> で囲む
変数の値の表示: <%= %> で囲む
(posts/index.html.erb)
<% post1 = “今日からProgateでRails” %>
<%= post1 %>
※ erb とは Embedded Ruby(埋め込みRuby) の略
・マイグレーションファイルの作成
$ rails g model Post content:text # Postモデルとpostsテーブルを作成するマイグレーションファイルの作成(text型のcontentカラム) $ rails db:migrate # データベースに変更を反映(エラーが発生するので必ず実行する) ※ 「rails g model Post ...」で以下のファイルが作成される tweet_app/app/models/post.rb # モデルが定義されたファイル tweet_app/db/migrate/2018MMDDHHMMSS_create_posts.rb # マイグレーションファイル
・コンソールの起動
$ rails console # コンソールの起動 > text = "Hello" # 変数に文字列を代入 > text # 変数の表示 "Hello" > post = Post.new(content: "Hello world") # Postインスタンスの作成 > post.save # Postインスタンスをテーブルに保存 > post = Post.first # postsテーブルの最初のデータをpost変数に代入 > post.content # 投稿内容(content)のみ出力 "Hello world" > posts = Post.all # テーブルにある全てのデータを配列で取得 > Post.all[0].content # 最初のデータの投稿内容を出力 "Hello world" > quit
・全ての投稿を表示する
# 配列(viewで使う変数はコントローラーのアクション内で定義) # (posts_controller.rb) def index @posts = Post.all end # each文で表示 # (posts/index.html.erb) <% @posts.each do |post| %> <%= post.content %> <% end %>
・「views/layouts/application.html.erb」に共通のHTMLを書いておくことができる
・リンクの追加
# (layouts/application.html.erb)
<%= link_to("About", "/about") %>
# 以下のaタグに変換される
# (application.html)
<a href="/about">About</a>
・完成版
# (2018MMDDHHMMHH_create_posts.rb)
def change
create_table :posts do |t|
t.text :content
t.timestamps
end
end
# (routes.rb)
get "posts/index" => "posts#index" # 追加
get "/" => "home#top"
get "about" => "home#about"
# (posts_controller.rb)
def index
@posts = Post.all
end
# (layouts/application.html.erb)
<header>
<div class="header-logo">
<%= link_to("TweetApp", "/") %>
</div>
<ul class="header-menus">
<li><%= link_to("TweetAppとは", "/about") %></li>
<li><%= link_to("投稿一覧", "/posts/index") %></li>
</ul>
</header>
# (posts/index.html.erb)
<% @posts.each do |post| %>
<div class="posts-index-item">
<%= post.content %>
</div>
<% end %>
・確認すること
- /(トップページ)が表示される
- ヘッダーメニューの「TweetAppとは」と「投稿一覧」にリンクが張られていて、画面遷移できる
- 投稿一覧に複数の投稿が表示できる
Ruby on Rails5 学習コースⅢ
・投稿詳細ページの作成
# (routes.rb) get "posts/:id" => "posts#show" # 「/posts/1」でも「/posts/2」でもshowアクションに遷移 # (posts_controller.rb) def show @post = Post.find_by(id: params[:id]) # idカラムがparams[:id]である投稿データを取得 end # (posts/show.html.erb) <%= @post.content %> <%= @post.created_at %>
・投稿詳細ページへのリンクを作成
# (posts/index.html.erb)
<% @posts.each do |post| %>
<%= link_to(post.content, "/posts/#{post.id}") %> # 変数展開を用いて投稿のidを指定
<% end %>
・投稿内容を受け取るアクションを用意
# (posts/new.html.erb)
<%= form_tag("/posts/create") do %> # form_tagメソッドを用いてフォームに入力されたデータを送信
<textarea name="content"></textarea> # name属性を指定することで入力データを送信できる
<input type="submit" value="投稿"> # 投稿ボタン
<% end %>
# (routes.rb)
post "posts/create" => "posts#create" # フォームの値を受け取る時は「post」を使う
# (posts_controller.rb)
def create
@post = Post.new(content: params[:content]) # contentが入力データであるインスタンスを作成
@post.save
redirect_to("/posts/index") # DBに保存後にリダイレクト
end
・特定のidの投稿を取得するためには、find_byメソッドを使用
$ rails c > post = Post.find_by(id: 3) > post.content "Rails勉強中!"
・他のURLに転送(リダイレクト)するには、redirect_toメソッドを使用
# (posts_controller.rb)
def create
redirect_to("/posts/index")
end
・orderメソッドを用いることで、投稿一覧を並び替えることができる
# (posts_controller.rb) def index @posts = Post.all.order(created_at: :desc) end
・完成版
# (routes.rb)
get "posts/index" => "posts#index"
get "posts/new" => "posts#new" # 追加
get "posts/:id" => "posts#show" # 追加
post "posts/create" => "posts#create" # 追加
get "/" => "home#top"
get "about" => "home#about"
# (posts_controller.rb)
def index
@posts = Post.all.order(created_at: :desc) # orderメソッドを使用
end
def show
@post = Post.find_by(id: params[:id])
end
def new
end
def create
@post = Post.new(content: params[:content])
@post.save
redirect_to("/posts/index")
end
# (layouts/application.html.erb)
<header>
<div class="header-logo">
<%= link_to("TweetApp", "/") %>
</div>
<ul class="header-menus">
<li><%= link_to("TweetAppとは", "/about") %></li>
<li><%= link_to("投稿一覧", "/posts/index") %></li>
<li><%= link_to("新規投稿", "/posts/new") %></li> # 追加
</ul>
</header>
# (posts/index.html.erb)
<% @posts.each do |post| %>
<div class="posts-index-item">
<%= link_to(post.content, "/posts/#{post.id}") %> # 変数展開を用いて投稿のidを指定
</div>
<% end %>
# (posts/show.html.erb)
<%= @post.content %>
<%= @post.created_at %>
# (posts/new.html.erb)
<%= form_tag("/posts/create") do %>
<div class="form">
<div class="form-body">
<textarea name="content"></textarea>
<input type="submit" value="投稿">
</div>
</div>
<% end %>
・確認すること
- 投稿一覧ページにて、新規の投稿から表示できている
- 投稿一覧ページの投稿内容のリンクから、投稿詳細ページへ画面遷移できる
- ヘッダーメニューの新規投稿リンクから、新規投稿ページへ画面遷移できる
- 新規投稿の内容が保存され、投稿一覧ページへリダイレクトされる
Ruby on Rails5 学習コースⅣ
・投稿を編集する
$ rails c > post = Post.find_by(id: 1) # DBから編集したい投稿を取得 > post.content = "Rails" # contentの値を上書き > post.destroy # destroyメソッドを使用して投稿を削除 > post.save # DBを保存(忘れがち!)
・編集ボタンの設置
# (posts/show.html.erb)
<%= link_to("編集", "/posts/#{@post.id}/edit") %> # editアクションのURLを指定
# (routes.rb)
get "posts/:id/edit" => "posts#edit"
・投稿内容をフォームの初期値にする
# (posts_controller.rb) def edit @post = Post.find_by(id: params[:id]) end # (posts/edit.html.erb) <textarea><%= @post.content %></textarea>
・編集機能を実装
# (posts/edit.html.erb)
<%= form_tag("/posts/#{@post.id}/update") do %> # form_tagで送信先のURLを指定
<textarea name="content"><%= @post.content %></textarea>
<input type="submit" value="保存">
<% end %>
# (routes.rb)
post "posts/:id/update" => "posts#update" # 値を受け取るのでpostにする
# (posts_controller.rb)
def update
@post = Post.find_by(id: params[:id])
@post.content = params[:content] # フォームの値を受け取ってDBへ代入
@post.save
redirect_to("/posts/index") # 投稿一覧ページへリダイレクト
end
・削除機能を実装
# (posts/show.html.erb)
# 「{method: "post"}」を追加することで、postで書かれているルーティングを探してくれる
<%= link_to("削除", "/posts/#{@post.id}/destroy", {method: "post"}) %>
# (routes.rb)
post "posts/:id/destroy" => "posts#destroy" # DBを変更するのでpostを使用
# (posts_controller.rb)
def destroy
@post = Post.find_by(id: params[:id])
@post.destroy
redirect_to("/posts/index") # 投稿一覧ページへリダイレクト
end
・完成版
# (routes.rb)
get "posts/index" => "posts#index"
get "posts/new" => "posts#new"
get "posts/:id" => "posts#show"
post "posts/create" => "posts#create"
get "posts/:id/edit" => "posts#edit" # 追加
post "posts/:id/update" => "posts#update" # 追加
post "posts/:id/destroy" => "posts#destroy" # 追加
get "/" => "home#top"
get "about" => "home#about"
# (posts_controller.rb)
def index
@posts = Post.all.order(created_at: :desc)
end
def show
@post = Post.find_by(id: params[:id])
end
def new
end
def create
@post = Post.new(content: params[:content])
@post.save
redirect_to("/posts/index")
end
# ここから追加
def edit
@post = Post.find_by(id: params[:id])
end
def update
@post = Post.find_by(id: params[:id])
@post.content = params[:content]
@post.save
redirect_to("/posts/index")
end
def destroy
@post = Post.find_by(id: params[:id])
@post.destroy
redirect_to("/posts/index")
end
# (posts/show.html.erb)
<%= @post.content %>
<%= @post.created_at %>
<%= link_to("編集", "/posts/#{@post.id}/edit") %> # 追加
<%= link_to("削除", "/posts/#{@post.id}/destroy", {method: "post"}) %> # 追加
# (posts/edit.html.erb)
<%= form_tag("/posts/#{@post.id}/update") do %>
<div class="form">
<div class="form-body">
<textarea name="content"><%= @post.content %></textarea>
<input type="submit" value="保存">
</div>
</div>
<% end %>
・確認すること
- 編集ボタンが設置されていて、投稿を編集でき、投稿内容がフォームの初期値になっている
- 削除ボタンが設置されていて、投稿を削除でき、投稿一覧へリダイレクトされる
Ruby on Rails5 学習コースⅤ
・バリデーションの実装
# (models/post.rb)
validates :content, {presence: true, length: {maximum: 140}} # 空の投稿を防ぎ、最大文字数を140文字に設定
・エラーメッセージの表示
# (posts_controller.rb)
def update
@post = Post.find_by(id: params[:id])
@post.content = params[:content]
if @post.save # 投稿の編集に成功した場合
redirect_to("/posts/index")
else # 投稿の編集に失敗した場合
render("posts/edit") # editアクションを経由せずにedit.html.erbを表示
end
end
# (posts/edit.html.erb)
<% @post.errors.full_messages.each do |message| %>
<%= message %>
<% end %>
・サクセスメッセージの表示
# 変数flashは1度表示された後に自動で削除される
# (posts_controller.rb)
def update
if @post.save
flash[:notice] = "投稿を編集しました"
:
end
# (layouts/application.html.erb)
<% if flash[:notice] %>
<%= flash[:notice] %> # フラッシュメッセージが存在する場合のみ、表示する
<% end %>
・完成版
# (models/port.rb)
validates :content, {presence: true, length: {maximum: 140}}
# (posts_controller.rb)
def index
@posts = Post.all.order(created_at: :desc)
end
def show
@post = Post.find_by(id: params[:id])
end
def new
@post = Post.new # 追記
end
def create
@post = Post.new(content: params[:content])
if @post.save
flash[:notice] = "投稿を作成しました" # 変数flash[:notice]を定義
redirect_to("/posts/index")
else
render("posts/new")
end
end
def edit
@post = Post.find_by(id: params[:id])
end
def update
@post = Post.find_by(id: params[:id])
@post.content = params[:content]
if @post.save # UPDATEの成否で条件分岐
flash[:notice] = "投稿を編集しました" # 変数flash[:notice]を定義
redirect_to("/posts/index")
else
render("posts/edit")
end
end
def destroy
@post = Post.find_by(id: params[:id])
@post.destroy
flash[:notice] = "投稿を削除しました" # 変数flash[:notice]を定義
redirect_to("/posts/index")
end
# (layouts/application.html.erb)
<% if flash[:notice] %>
<div class="flash">
<%= flash[:notice] %> # フラッシュメッセージが存在する場合のみ、表示する
</div>
<% end %>
# (posts/edit.html.erb)
<%= form_tag("/posts/#{@post.id}/update") do %>
<div class="form">
<div class="form-body">
<% @post.errors.full_messages.each do |message| %>
<div class="form-error">
<%= message %> # エラーメッセージを出力
</div>
<% end %>
<textarea name="content"><%= @post.content %></textarea>
<input type="submit" value="保存">
</div>
</div>
<% end %>
# (posts/new.html.erb)
<%= form_tag("/posts/create") do %>
<div class="form">
<div class="form-body">
<% @post.errors.full_messages.each do |message| %>
<div class="form-error">
<%= message %>
</div>
<% end %>
<textarea name="content"><%= @post.content %></textarea>
<input type="submit" value="投稿">
</div>
</div>
<% end %>
・確認すること
- 新規投稿に成功した場合、サクセスメッセージが表示される
- 新規投稿に失敗した場合(空の投稿、文字数が140文字より大きい場合)、エラーメッセージが表示され、新規投稿ページに戻る
- 投稿の編集に成功した場合、サクセスメッセージが表示される
- 投稿の編集に失敗した場合(空の投稿、文字数が140文字より大きい場合)、エラーメッセージが表示され、編集ページに戻る
- 投稿を削除した際、サクセスメッセージが表示される
[siteorigin_widget class=”AdWidgetItem”][/siteorigin_widget]
[siteorigin_widget class=”WP_Widget_Search”][/siteorigin_widget]
[siteorigin_widget class=”WP_Widget_Pages”][/siteorigin_widget]
[siteorigin_widget class=”AdWidgetItem”][/siteorigin_widget]
