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]