-
Notifications
You must be signed in to change notification settings - Fork 0
board_001
このセクションで行うことは以下である。
- Thread モデルの作成
- Thread のデータ一覧参照画面、データ登録画面、データ詳細参照画面の作成
作成する Thread モデルのとりあえずの構成は以下とする。
| Column | Type | Note |
|---|---|---|
| id | integer | スレッド ID。 |
| title | string | スレッドのタイトル。 |
| user_id | integer | スレッドの作成者 |
| created_at | datetime | スレッドの作成日時 |
| updated_at | datetime | スレッドの更新日時 |
以下の 通りにrails generate modelを利用して モデルを作成する。id, created_at, updated_atはモデル作成時に自動で作成されるので、 コンソールからの指定は不要である。
$ bin/rails g model board_thread title:string user_id:integer
invoke active_record
create db/migrate/20180102125048_create_board_threads.rb
create app/models/board_thread.rb
db/migrate/20180102125048_create_board_threads.rb の中身を 見てみると、
class CreateBoardThreads < ActiveRecord::Migration[5.1]
def change
create_table :board_threads do |t|
t.string :title
t.integer :user_id
t.timestamps
end
end
end
となっている。rails generate model時にカラムの 設定を忘れた等場合、このファイルを編集すれば後からモデル構成を変えることができる。t.string :titleのようにt.型 :カラム名 の形式で編集追加を行えば良い。
作成した migrate ファイルから実際に DB にテーブルを作成する。
$ bin/rake db:migrate
== 20180102125048 CreateBoardThreads: migrating ===============================
-- create_table(:board_threads)
-> 0.0063s
== 20180102125048 CreateBoardThreads: migrated (0.0064s) ======================
$ psql -U postgres
postgres=# \c learnrails_develop
learnrails_development=# \d
learnrails_development=# \d board_threads
migrate の内容を間違えた場合は、bin/rake db:rollbackをすることでbin/rails migrateの実行前の状態に戻すことができる。
あるいは、bin/rake db:migrate:resetを実行すると DB を初期化して migrate を実行し直すことができる。
データ一覧参照画面を作成した時に 表示確認のためのデータを作成しておく。Postgresql から登録しても良いが、練習のためrails consoleからデータ登録してみる。
$ bin/rails c
> BoardThread.create(title: 'Rails を学ぶ', user_id: 1)
> BoardThread.create(title: 'Ruby を学ぶ', user_id: 2)
> BoardThread.all
BoardThreadモデルのcreateメソッドを利用するとデータの Insert が行える。またBoardTheadモデルのallメソッドでテーブル内の全データを select できる。
rails generate controllerを利用してコントローラーを作成する。同時にアクションを作成できるが、後から作成できるので指定していない。アクションを作成する場合はrails generate controller コントローラー名 アクション名 アクション名 ...とすれば作成される。 ここでは、掲示板のコントローラーをサブディレクトリに分けるためにboard::と namespace を指定しているが、必要がなければ省いて良い。
$ bin/rails g controller board::threads
create app/controllers/board/threads_controller.rb
invoke haml
create app/views/board/threads
config/routes.rbを編集してルーティングを設定する。
Rails には規則として決まったアクションが存在する。以下の通りである。
| action | Note |
|---|---|
| index | データ一覧画面 |
| create | データ作成処理 |
| new | データ作成の入力画面 |
| edit | データ更新画面 |
| show | データ詳細画面 |
| update | データ 更新処理 |
| destroy | データ削除処理 |
ルーティングでは必要なアクション 分のものだけを用意すればいいが、resourcesを利用すれば一度に全アクションを追加できる。試しにconfig/routes.rbに追加してみる 。
Rails.application.routes.draw do
namespace :board do
resources :threads
end
end
コンソールからルーティングを確認してみると、
$ bin/rake routes
Prefix Verb URI Pattern Controller#Action
board_threads GET /board/threads(.:format) board/threads#index
POST /board/threads(.:format) board/threads#create
new_board_thread GET /board/threads/new(.:format) board/threads#new
edit_board_thread GET /board/threads/:id/edit(.:format) board/threads#edit
board_thread GET /board/threads/:id(.:format) board/threads#show
PATCH /board/threads/:id(.:format) board/threads#update
PUT /board/threads/:id(.:format) board/threads#update
DELETE /board/threads/:id(.:format) board/threads#destroy
と全てのアクションに対してのルーティングが設定されている。
このままでもよいが、ここでは個別にルーティングの設定を行うことにする。
Rails.application.routes.draw do
namespace :board do
get '/threads' => 'threads#index'
post '/threads' => 'threads#create'
get '/threads/new' => 'threads#new'
get '/threads/:id' => 'threads#show'
end
end
コントローラー作成時に namespace を設定しなかった場合は、namespace :board doは不要である。
ルーティング設定の順番には注意が必要である。newの ルート設定をshow の 次の行に記述すると/threads/new とブラウザから入った時に、/newを/:idと認識されshowの画面が表示されてしまう。
ルーティングが設定されたかコンソールから確認してみる。
$ bin/rake routes
Prefix Verb URI Pattern Controller#Action
board_threads GET /board/threads(.:format) board/threads#index
POST /board/threads(.:format) board/threads#create
board_threads_new GET /board/threads/new(.:format) board/threads#new
board GET /board/threads/:id(.:format) board/threads#show
app/controllers/board/threads_contorller.rbにアクションを追加する。
class Board::ThreadsController < ApplicationController
def index
end
def create
end
def new
end
def show
end
end
とりあえず追加したアクションはindex, create, new, showである。
indexアクションを編集する。
def index
@threads = BoardThead.all
end
モデルの allメソッドを利用し、 全データを取得しインスタンス変数に 詰めておく。
次にビュー側を作成する。ビューは app/views/board/threads 配下にファイルを用意する。 デフォルトであれば、erb テンプレートを利用するが、今回は haml というテンプレートエンジンを利用する。
erb の場合は以下のようにファイルを作成する。
<h1>掲示板</h1>
<h2><%= link_to 'スレッドを作成する', board_threads_new_path %></h2>
<h2>スレッド一覧</h2>
<ul>
<%= @threads.each do |thread| %>
<li><%= link_to thread.title, board_path(thread.id) %></li>
<% end %>
</ul>
ここでは、haml を利用するので以下のようにファイルを作成する。
%h1 掲示板
%h2= link_to 'スレッドを作成する', board_threads_new_path
%h2 スレッド一覧
%ul
- @threads.each do |thread|
%li= link_to thread.title, board_path(thread.id)
link_toを利用するとページへのリンクを用意できる。board_thread_new_pathとあるのは/board/threads/newの URL ことである。パスの表記は、bin/rake routesで表示されるPrefixの末尾に_pathを付与すればよい。
- Rails でリンクパスを生成する方法色々・・と Rails console で 生成される path を確認したい時
- http://haml.info/tutorial.html
- 【rails】haml の使い方
- Haml が 5 分で分るチートシート
「スレッドを 作成する」リンクからの遷移先画面を用意する。ルーティングは設定済みなのでコントローラーの用意と ビューの用意をする。
ef create
@thread = BoardThread.new(thread_params)
@thread.save
redirect_to board_threads_path
end
def new
@thread = BoardThread.new
end
private
def thread_params
params.require(:board_thread).permit(:title, :user_id)
end
データ作成処理を行うcreateアクションとデータ入力画面のnewアクションを編集する。
createについて、thread = BoardThread.new(thread_params)で入力画面からもらった内容でスレッドのモデルオブジェクトを作成する。thread_paramsはプライベートメソッドで、セキュリティのためにtitleとuser_idのみを受け付けるようにしている。下記参考の URL に詳しく解説されている記事があった。
次に、@thread.saveでモデルオブジェクトをもとに DB に保存する。保存後は一覧画面に遷移する。
newについて、入力画面で入力した内容を格納しておくためのオブジェクトを用意する。あとはビュー側で入力データを格納すればよい。
%h1 スレッドの作成
= form_for @thread do |f|
%div.input
= f.label :title, 'タイトル'
= f.text_field :title
= f.hidden_field :user_id, value: 1
%div.button
= f.submit '作成'
フォームの作成はform_forメソッドを利用して実装する。このメソッドを利用すれば、様々なフォームを用意することができる。 今回はf.text_fieldを利用してテキストボックスを、f.submitを利用して送信ボタンを用意している。
user_idはまだ色々と準備ができていないので、とりあえず 1固定で登録されるようにしている。今回利用したフォームはこれだけだが、利用できるフォームは色々のでいずれまた使う機会を設ける。下記参考によく使うフォームの説明があるので参照するとよい。
以上で登録画面の作成は完了である。実際に入力画面よりデータ登録が行えるか動作確認を行なっておくとよい。
- 【Ruby on Rails】require と permit の使い方がよく分からない
- 【永久保存版】Rails の form_for 使い方まとめ(select, url, checkbox, number etc….)
一覧画面からスレッドタイトルのリンクをクリック した時の遷移画面を作成する。
#### Post モデルの作成
rails generate model コマンドを使って投稿情報を保存するモデルを作成する。
$ bin/rails g model board_post user_id:integer body:text board_thread:references
invoke active_record
create db/migrate/20180104142519_create_board_posts.rb
create app/models/board_post.rb
$ bin/rake db:migrate
== 20180104142519 CreateBoardPosts: migrating =================================
-- create_table(:board_posts)
-> 0.0147s
== 20180104142519 CreateBoardPosts: migrated (0.0147s) ========================
Thread モデルを用意したように、Post モデルも用意する。
board_thread:referencesで Thread の ID を外部キーとして設定しています。Migration ファイルをみてみると、
class CreateBoardPosts < ActiveRecord::Migration[5.1]
def change
create_table :board_posts do |t|
t.integer :user_id
t.text :body
t.references :board_thread, foreign_key: true
t.timestamps
end
end
end
となっており、foreign_key: trueが付与されている。 マイグレーション後にschema.rbに反映された内容をみると、
create_table "board_posts", force: :cascade do |t|
t.integer "user_id"
t.text "body"
t.bigint "board_thread_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["board_thread_id"], name: "index_board_posts_on_board_thread_id"
end
また、 モデルファイル board_post.rbは、
class BoardPost < ApplicationRecord
belongs_to :board_thread
end
と、belongs_toでboard_threadに従属関係ができているのがわかる。
def show
@thread = BoardThread.find(params[:id])
@posts = BoardPost.where(board_thread_id: params[:id]).order('created_at DESC')
end
モデルのfindメソッドを使用して、スレッドの ID からスレッド情報を取得する。さらに Post データはモデルのwhereメソッドを使用して、スレッド ID が一致する投稿データを全て取得する。また、orderメソッドを利用して最新の投稿が画面トップに表示されるように並び替えている。
%h1= @thread.title
- @posts.each do |post|
%p= "No.#{post.id} #{post.created_at.strftime('%m/%d/%Y(%a) %H:%M:%S')} ID:#{post.user_id}"
%p= post.body
%hr/
ビュー側はコントローラーで取得した投稿データをeachでループして1件毎に表示している。