RubyonRailsアプリケーションのネストされたリソースを作成する方法
序章
Ruby on Rails は、 Ruby で記述されたWebアプリケーションフレームワークであり、開発者にアプリケーション開発への意見のあるアプローチを提供します。 Railsを使用すると、開発者は次のことができます。
- ルーティング、ステートフルデータ、アセット管理などを処理するための規則。
- model-view-controller (MCV)アーキテクチャパターンの確固たる基盤。これにより、モデル内にあるアプリケーションのロジックが、アプリケーション情報の表示とルーティングから分離されます。
Railsアプリケーションに複雑さを加えると、アプリケーションのビジネスロジックとデータベースとのインターフェイスを表す複数のモデルを使用する可能性が高くなります。 関連するモデルを追加するということは、それらの間に意味のある関係を確立することを意味します。これは、情報がアプリケーションのコントローラーを介して中継される方法、および情報がキャプチャされ、ビューを介してユーザーに提示される方法に影響します。
このチュートリアルでは、サメに関する事実をユーザーに提供する既存のRailsアプリケーションに基づいて構築します。 このアプリケーションにはすでにサメのデータを処理するためのモデルがありますが、個々のサメに関する投稿用にネストされたリソースを追加します。 これにより、ユーザーは個々のサメについての幅広い考えや意見を構築することができます。
前提条件
このチュートリアルに従うには、次のものが必要です。
- Ubuntu18.04を実行しているローカルマシンまたは開発サーバー。 開発マシンには、管理者権限を持つroot以外のユーザーと、
ufw
で構成されたファイアウォールが必要です。 これを設定する方法については、 Ubuntu18.04を使用した初期サーバー設定のチュートリアルを参照してください。 - Node.jsおよびnpmがローカルマシンまたは開発サーバーにインストールされています。 このチュートリアルでは、Node.jsバージョン10.16.3とnpmバージョン6.9.0を使用します。 Ubuntu 18.04にNode.jsとnpmをインストールする手順については、 Ubuntu18.04にNode.jsをインストールする方法の「PPAを使用したインストール」セクションの手順に従ってください。
- Ubuntu18.04でrbenvを使用してRubyonRailsをインストールする方法の手順1〜4に従って、ローカルマシンまたは開発サーバーにインストールされたRuby、 rbenv 、およびRails。 このチュートリアルでは、Ruby 2.5.1 、rbenv 1.1.2 、およびRails 5.2.3を使用します。
- Ruby on Railsアプリケーションの構築方法の指示に従って、SQLiteをインストールし、基本的なサメ情報アプリケーションを作成しました。
ステップ1—ネストされたモデルの足場
私たちのアプリケーションは、Active Recordアソシエーションを利用してShark
モデルとPost
モデル間の関係を構築します。投稿は特定のサメに属し、各サメは複数の投稿を持つことができます。 したがって、Shark
およびPost
モデルは、belongs_toおよびhas_manyの関連付けによって関連付けられます。
この方法でアプリケーションを構築するための最初のステップは、Post
モデルと関連リソースを作成することです。 これを行うには、rails generate scaffold
コマンドを使用して、モデル、データベース移行を使用してデータベーススキーマ、コントローラー、標準を管理するためのビューのフルセットを提供します。 X187X] Create、Read、Update、およびDelete (CRUD)操作、およびパーシャル、ヘルパー、およびテスト用のテンプレート。 これらのリソースを変更する必要がありますが、scaffold
コマンドを使用すると、開始点として使用できる構造が生成されるため、時間とエネルギーを節約できます。
まず、前提条件で作成したRailsプロジェクトのsharkapp
ディレクトリにいることを確認します。
cd sharkapp
次のコマンドを使用して、Post
リソースを作成します。
rails generate scaffold Post body:text shark:references
body:text
を使用して、Railsにbody
フィールドをposts
データベーステーブル(Post
モデルにマップするテーブル)に含めるように指示しています。 :references
キーワードも含まれています。これはShark
モデルとPost
モデル間の関連付けを設定します。 具体的には、これにより、sharks
データベースの各サメエントリを表す外部キーがposts
データベースに追加されます。
コマンドを実行すると、Railsがアプリケーション用に生成したリソースを確認する出力が表示されます。 先に進む前に、データベース移行ファイルをチェックして、モデルとデータベーステーブルの間に現在存在する関係を確認できます。 次のコマンドを使用してファイルの内容を確認し、ここに表示されているものを自分の移行ファイルのタイムスタンプに置き換えてください。
cat db/migrate/20190805132506_create_posts.rb
次の出力が表示されます。
Outputclass CreatePosts < ActiveRecord::Migration[5.2] def change create_table :posts do |t| t.text :body t.references :shark, foreign_key: true t.timestamps end end end
ご覧のとおり、テーブルにはサメの外部キーの列が含まれています。 このキーはmodel_name_id
の形式を取ります—この場合はshark_id
です。
Railsは他の場所でもモデル間の関係を確立しています。 次のコマンドを使用して、新しく生成されたPost
モデルを確認します。
cat app/models/post.rb
Outputclass Post < ApplicationRecord belongs_to :shark end
belongs_to
アソシエーションは、宣言モデルの単一インスタンスが名前付きモデルの単一インスタンスに属するモデル間の関係を設定します。 私たちのアプリケーションの場合、これは単一の投稿が単一のサメに属することを意味します。
この関係の設定に加えて、rails generate scaffold
コマンドは、 How To Build Ruby on Railsのステップ3のサメリソースの場合と同様に、投稿のルートとビューも作成しました。アプリケーション。
これは便利なスタートですが、モデルとルートの関係が希望どおりに機能するためには、追加のルーティングを構成し、Shark
モデルのアクティブレコードの関連付けを固める必要があります。
ステップ2—親モデルのネストされたルートと関連付けを指定する
Railsは、rails generate scaffold
コマンドの:references
キーワードのおかげで、Post
モデルにbelongs_to
の関連付けを既に設定していますが、その関係が機能するために適切には、Shark
モデルでもhas_many
の関連付けを指定する必要があります。 また、投稿リソースをサメリソースの子にするために、Railsが提供するデフォルトのルーティングを変更する必要があります。
has_many
アソシエーションをShark
モデルに追加するには、nano
またはお気に入りのエディターを使用してapp/models/shark.rb
を開きます。
nano app/models/shark.rb
次の行をファイルに追加して、サメと投稿の関係を確立します。
〜/ sharkapp / app / models / shark.rb
class Shark < ApplicationRecord has_many :posts validates :name, presence: true, uniqueness: true validates :facts, presence: true end
ここで検討する価値のあることの1つは、特定のサメが削除されると投稿がどうなるかということです。 削除されたサメに関連付けられた投稿をデータベースに残したくない場合があります。 特定のサメが削除されたときに、そのサメに関連付けられている投稿が確実に削除されるように、dependent
オプションを関連付けに含めることができます。
次のコードをファイルに追加して、特定のサメに対するdestroy
アクションで関連する投稿が削除されるようにします。
〜/ sharkapp / app / models / shark.rb
class Shark < ApplicationRecord has_many :posts , dependent: :destroy validates :name, presence: true, uniqueness: true validates :facts, presence: true end
これらの変更が完了したら、ファイルを保存して閉じます。 nano
を使用している場合は、CTRL+X
、Y
、ENTER
の順に押すとこれを行うことができます。
次に、config/routes.rb
ファイルを開いて、リソースの多いルート間の関係を変更します。
nano config/routes.rb
現在、ファイルは次のようになっています。
〜/sharkapp/config/routes.rb
Rails.application.routes.draw do resources :posts resources :sharks root 'sharks#index' # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end
現在のコードは、ルート間に独立した関係を確立しています。表現したいのは、サメとそれに関連する投稿の間の依存関係です。
ルート宣言を更新して、:sharks
を:posts
の親にします。 ファイル内のコードを次のように更新します。
〜/sharkapp/config/routes.rb
Rails.application.routes.draw do resources :sharks do resources :posts end root 'sharks#index' # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end
編集が終了したら、ファイルを保存して閉じます。
これらの変更を行うと、posts
コントローラーの更新に進むことができます。
ステップ3—投稿コントローラーを更新する
モデル間の関連付けにより、特定のサメに関連付けられた新しい投稿インスタンスを作成するために使用できるメソッドが提供されます。 これらのメソッドを使用するには、postsコントローラーを追加する必要があります。
投稿コントローラーファイルを開きます。
nano app/controllers/posts_controller.rb
現在、ファイルは次のようになっています。
〜/ sharkapp / controllers / posts_controller.rb
class PostsController < ApplicationController before_action :set_post, only: [:show, :edit, :update, :destroy] # GET /posts # GET /posts.json def index @posts = Post.all end # GET /posts/1 # GET /posts/1.json def show end # GET /posts/new def new @post = Post.new end # GET /posts/1/edit def edit end # POST /posts # POST /posts.json def create @post = Post.new(post_params) respond_to do |format| if @post.save format.html { redirect_to @post, notice: 'Post was successfully created.' } format.json { render :show, status: :created, location: @post } else format.html { render :new } format.json { render json: @post.errors, status: :unprocessable_entity } end end end # PATCH/PUT /posts/1 # PATCH/PUT /posts/1.json def update respond_to do |format| if @post.update(post_params) format.html { redirect_to @post, notice: 'Post was successfully updated.' } format.json { render :show, status: :ok, location: @post } else format.html { render :edit } format.json { render json: @post.errors, status: :unprocessable_entity } end end end # DELETE /posts/1 # DELETE /posts/1.json def destroy @post.destroy respond_to do |format| format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_post @post = Post.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def post_params params.require(:post).permit(:body, :shark_id) end end
sharksコントローラーと同様に、このコントローラーのメソッドは、関連付けられたPost
クラスのインスタンスで機能します。 たとえば、new
メソッドはPost
クラスの新しいインスタンスを作成し、index
メソッドはクラスのすべてのインスタンスを取得し、set_post
メソッドはfind
およびparams
は、id
で特定の投稿を選択します。 ただし、postインスタンスを特定のsharkインスタンスに関連付ける場合は、Post
クラスが現在独立したエンティティとして動作しているため、このコードを変更する必要があります。
私たちの変更は2つのことを利用します:
- モデルに
belongs_to
およびhas_many
の関連付けを追加したときに使用可能になったメソッド。 具体的には、Shark
モデルで定義したhas_many
アソシエーションのおかげで、ビルドメソッドにアクセスできるようになりました。 このメソッドを使用すると、posts
データベースに存在するshark_id
外部キーを使用して、特定のsharkオブジェクトに関連付けられたpostオブジェクトのコレクションを作成できます。 - ネストされた
posts
ルートを作成したときに使用可能になったルートとルーティングヘルパー。 リソース間にネストされた関係を作成するときに使用可能になるルート例の完全なリストについては、Railsのドキュメントを参照してください。 今のところ、特定のサメ(たとえば、sharks/1
)ごとに、そのサメに関連する投稿に関連付けられたルートsharks/1/posts
があることを知っていれば十分です。 これらのネストされたルートを参照するshark_posts_path(@shark)
やedit_sharks_posts_path(@shark)
などのルーティングヘルパーもあります。
このファイルでは、まず、コントローラーの各アクションの前に実行されるメソッドget_shark
を記述します。 このメソッドは、shark_id
によってサメのインスタンスを見つけることにより、ローカルの@shark
インスタンス変数を作成します。 この変数をファイルで使用できるため、他の方法で投稿を特定のサメに関連付けることができます。
ファイルの下部にある他のprivate
メソッドの上に、次のメソッドを追加します。
〜/ sharkapp / controllers / posts_controller.rb
. . . private def get_shark @shark = Shark.find(params[:shark_id]) end # Use callbacks to share common setup or constraints between actions. . . .
次に、既存のフィルターの前に、対応するフィルターをファイルのtopに追加します。
〜/ sharkapp / controllers / posts_controller.rb
class PostsController < ApplicationController before_action :get_shark
これにより、ファイルで定義された各アクションの前にget_shark
が実行されます。
次に、この@shark
インスタンスを使用して、index
メソッドを書き直すことができます。 Post
クラスのすべてのインスタンスを取得する代わりに、このメソッドが特定のsharkインスタンスに関連付けられているすべてのpostインスタンスを返すようにします。
index
メソッドを次のように変更します。
〜/ sharkapp / controllers / posts_controller.rb
. . . def index @posts = @shark.posts end . . .
new
メソッドでは、新しいpostインスタンスを特定のサメに関連付ける必要があるため、同様のリビジョンが必要になります。 これを実現するために、ローカルの@shark
インスタンス変数とともにbuild
メソッドを使用できます。
new
メソッドを次のように変更します。
〜/ sharkapp / controllers / posts_controller.rb
. . . def new @post = @shark.posts.build end . . .
このメソッドは、get_shark
メソッドから特定のsharkインスタンスに関連付けられたpostオブジェクトを作成します。
次に、new
に最も密接に関連する方法create
について説明します。 create
メソッドは2つのことを行います。ユーザーがnew
フォームに入力したパラメーターを使用して新しい投稿インスタンスを作成し、エラーがない場合はそのインスタンスを保存して、ヘルパーをルーティングして、ユーザーを新しい投稿を表示できる場所にリダイレクトします。 エラーが発生した場合は、new
テンプレートが再度レンダリングされます。
create
メソッドを次のように更新します。
〜/ sharkapp / controllers / posts_controller.rb
def create @post = @shark.posts.build(post_params) respond_to do |format| if @post.save format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully created.' } format.json { render :show, status: :created, location: @post } else format.html { render :new } format.json { render json: @post.errors, status: :unprocessable_entity } end end end
次に、update
メソッドを見てみましょう。 このメソッドは、@post
インスタンス変数を使用しますが、これはメソッド自体に明示的に設定されていません。 この変数はどこから来たのですか?
ファイルの上部にあるフィルターを見てください。 2番目の自動生成されたbefore_action
フィルターは、次の答えを提供します。
〜/ sharkapp / controllers / posts_controller.rb
class PostsController < ApplicationController before_action :get_shark before_action :set_post, only: [:show, :edit, :update, :destroy] . . .
update
メソッド(show
、edit
、destroy
など)は、set_post
メソッドから@post
変数を取得します。 get_shark
メソッドと他のprivate
メソッドの下にリストされているそのメソッドは、現在次のようになっています。
〜/ sharkapp / controllers / posts_controller.rb
. . . private . . . def set_post @post = Post.find(params[:id]) end . . .
ファイルの他の場所で使用したメソッドを維持するために、このメソッドを変更して、@post
が特定の投稿のコレクション内の特定のインスタンスを参照するようにする必要があります。鮫。 ここでは、build
メソッドを念頭に置いてください。モデル間の関連付けと、それらの関連付けによって利用できるメソッド(build
など)のおかげで、各投稿インスタンスは次のようになります。特定のサメに関連付けられているオブジェクトのコレクションの一部。 したがって、特定の投稿をクエリするときに、特定のサメに関連付けられている投稿のコレクションをクエリすることは理にかなっています。
set_post
を次のように更新します。
〜/ sharkapp / controllers / posts_controller.rb
. . . private . . . def set_post @post = @shark.posts.find(params[:id]) end . . .
id
によってPost
クラス全体の特定のインスタンスを検索する代わりに、特定のサメに関連付けられた投稿のコレクションで一致するid
を検索します。
そのメソッドが更新されると、update
およびdestroy
メソッドを確認できます。
update
メソッドは、set_post
の@post
インスタンス変数を使用し、ユーザーが[に入力したpost_params
で使用します。 X150X]フォーム。 成功した場合は、Railsがユーザーを特定のサメに関連付けられた投稿のindex
ビューに戻すようにします。 エラーが発生した場合、Railsはedit
テンプレートを再度レンダリングします。
この場合、正常な更新を処理するために必要な変更は、redirect_to
ステートメントのみです。 更新してshark_post_path(@shark)
にリダイレクトします。これにより、選択したサメの投稿のindex
ビューにリダイレクトされます。
〜/ sharkapp / controllers / posts_controller.rb
. . . def update respond_to do |format| if @post.update(post_params) format.html { redirect_to shark_post_path(@shark), notice: 'Post was successfully updated.' } format.json { render :show, status: :ok, location: @post } else format.html { render :edit } format.json { render json: @post.errors, status: :unprocessable_entity } end end end . . .
次に、destroy
メソッドに同様の変更を加えます。 redirect_to
メソッドを更新して、成功した場合にリクエストをshark_posts_path(@shark)
にリダイレクトします。
〜/ sharkapp / controllers / posts_controller.rb
. . . def destroy @post.destroy respond_to do |format| format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully destroyed.' } format.json { head :no_content } end end . . .
これが最後の変更です。 これで、次のような投稿コントローラーファイルが作成されました。
〜/ sharkapp / controllers / posts_controller.rb
class PostsController < ApplicationController before_action :get_shark before_action :set_post, only: [:show, :edit, :update, :destroy] # GET /posts # GET /posts.json def index @posts = @shark.posts end # GET /posts/1 # GET /posts/1.json def show end # GET /posts/new def new @post = @shark.posts.build end # GET /posts/1/edit def edit end # POST /posts # POST /posts.json def create @post = @shark.posts.build(post_params) respond_to do |format| if @post.save format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully created.' } format.json { render :show, status: :created, location: @post } else format.html { render :new } format.json { render json: @post.errors, status: :unprocessable_entity } end end end # PATCH/PUT /posts/1 # PATCH/PUT /posts/1.json def update respond_to do |format| if @post.update(post_params) format.html { redirect_to shark_post_path(@shark), notice: 'Post was successfully updated.' } format.json { render :show, status: :ok, location: @post } else format.html { render :edit } format.json { render json: @post.errors, status: :unprocessable_entity } end end end # DELETE /posts/1 # DELETE /posts/1.json def destroy @post.destroy respond_to do |format| format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully destroyed.' } format.json { head :no_content } end end private def get_shark @shark = Shark.find(params[:shark_id]) end # Use callbacks to share common setup or constraints between actions. def set_post @post = @shark.posts.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def post_params params.require(:post).permit(:body, :shark_id) end end
コントローラは、情報がビューテンプレートからデータベースに、またはその逆に渡される方法を管理します。 私たちのコントローラーは、Shark
モデルとPost
モデルの間の関係を反映するようになりました。このモデルでは、投稿が特定のサメに関連付けられています。 ビューテンプレート自体の変更に進むことができます。ここで、ユーザーは特定のサメに関する投稿情報を渡し、変更します。
ステップ4—ビューを変更する
ビューテンプレートの改訂には、投稿に関連するテンプレートの変更と、特定のサメに関連付けられた投稿をユーザーに表示するためのサメshow
ビューの変更が含まれます。
投稿の基本的なテンプレートから始めましょう。複数の投稿テンプレートで再利用されるform
パーシャルです。 今すぐそのフォームを開きます:
nano app/views/posts/_form.html.erb
post
モデルのみをform_with
フォームヘルパーに渡すのではなく、shark
モデルとpost
モデルの両方をpost
とともに渡します。子リソースとして設定します。
ファイルの最初の行を次のように変更します。これは、サメと投稿リソースの関係を反映しています。
〜/sharkapp/views/posts/_form.html.erb
<%= form_with(model: [@shark, post], local: true) do |form| %> . . .
次に、 delete は、関連するサメのshark_id
をリストするセクションです。これは、ビューの重要な情報ではないためです。
最初の行を編集し、shark_id
セクションを削除せずに完成したフォームは、次のようになります。
〜/sharkapp/views/posts/_form.html.erb
<%= form_with(model: [@shark, post], local: true) do |form| %> <% if post.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2> <ul> <% post.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= form.label :body %> <%= form.text_area :body %> </div> <div class="actions"> <%= form.submit %> </div> <% end %>
編集が終了したら、ファイルを保存して閉じます。
次に、index
ビューを開きます。このビューには、特定のサメに関連する投稿が表示されます。
nano app/views/posts/index.html.erb
rails generate scaffold
コマンドのおかげで、Railsはテンプレートの大部分を生成し、各投稿のbody
フィールドとそれに関連するshark
を示すテーブルを完成させました。
ただし、すでに変更した他のコードと同様に、このテンプレートは、モデルとコレクションの間の関連付け、およびこれらの関連付けによって提供されるヘルパーメソッドを利用する場合、投稿を独立したエンティティとして扱います。
表の本文で、次の更新を行います。
まず、post.shark
をpost.shark.name
に更新します。これにより、テーブルには、サメオブジェクト自体に関する情報ではなく、関連付けられたサメの名前フィールドが含まれます。
〜/sharkapp/app/views/posts/index.html.erb
. . . <tbody> <% @posts.each do |post| %> <tr> <td><%= post.body %></td> <td><%= post.shark.name %></td> . . .
次に、Show
リダイレクトを変更して、関連するサメのshow
ビューにユーザーを誘導します。これは、元のサメに戻る方法が必要になる可能性が高いためです。 Railsはコントローラーで作成されたインスタンス変数をすべてのビューで使用できるようにするため、ここでコントローラーに設定した@shark
インスタンス変数を利用できます。 また、リンクのテキストをShow
からShow Shark
に変更して、ユーザーがその機能をよりよく理解できるようにします。
この行を次のように更新します。
〜/sharkapp/app/views/posts/index.html.erb
. . . <tbody> <% @posts.each do |post| %> <tr> <td><%= post.body %></td> <td><%= post.shark.name %></td> <td><%= link_to 'Show Shark', [@shark] %></td>
次の行では、ユーザーが投稿を編集するときに、正しいネストされたパスにルーティングされるようにします。 これは、ユーザーがposts/post_id/edit
に誘導されるのではなく、sharks/shark_id/posts/post_id/edit
に誘導されることを意味します。 これを行うには、shark_post_path
ルーティングヘルパーと、RailsがURLとして扱うモデルを使用します。 また、リンクテキストを更新して、その機能を明確にします。
Edit
行を次のように更新します。
〜/sharkapp/app/views/posts/index.html.erb
. . . <tbody> <% @posts.each do |post| %> <tr> <td><%= post.body %></td> <td><%= post.shark.name %></td> <td><%= link_to 'Show Shark', [@shark] %></td> <td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td>
次に、Destroy
リンクに同様の変更を追加し、文字列内の関数を更新して、shark
およびpost
リソースを追加しましょう。
〜/sharkapp/app/views/posts/index.html.erb
. . . <tbody> <% @posts.each do |post| %> <tr> <td><%= post.body %></td> <td><%= post.shark.name %></td> <td><%= link_to 'Show Shark', [@shark] %></td> <td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td> <td><%= link_to 'Destroy Post', [@shark, post], method: :delete, data: { confirm: 'Are you sure?' } %></td>
最後に、フォームの下部で、New Post
パスを更新して、ユーザーが新しい投稿を作成するときに適切なネストされたパスに移動できるようにします。 ファイルの最後の行を更新して、new_shark_post_path(@shark)
ルーティングヘルパーを利用します。
〜/sharkapp/app/views/posts/index.html.erb
. . . <%= link_to 'New Post', new_shark_post_path(@shark) %>
完成したファイルは次のようになります。
〜/sharkapp/app/views/posts/index.html.erb
<p id="notice"><%= notice %></p> <h1>Posts</h1> <table> <thead> <tr> <th>Body</th> <th>Shark</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @posts.each do |post| %> <tr> <td><%= post.body %></td> <td><%= post.shark.name %></td> <td><%= link_to 'Show Shark', [@shark] %></td> <td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td> <td><%= link_to 'Destroy Post', [@shark, post], method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table> <br> <%= link_to 'New Post', new_shark_post_path(@shark) %>
編集が終了したら、ファイルを保存して閉じます。
ビューを投稿するために行う他の編集は、他のビューがすでに編集したform
部分を使用しているため、それほど多くはありません。 ただし、form
パーシャルに加えた変更を反映するために、他の投稿テンプレートのlink_to
参照を更新する必要があります。
app/views/posts/new.html.erb
を開きます:
nano app/views/posts/new.html.erb
ファイルの下部にあるlink_to
参照を更新して、shark_posts_path(@shark)
ヘルパーを使用します。
〜/ sharkapp / app / views / posts / new.html.erb
. . . <%= link_to 'Back', shark_posts_path(@shark) %>
この変更が完了したら、ファイルを保存して閉じます。
次に、edit
テンプレートを開きます。
nano app/views/posts/edit.html.erb
Back
パスに加えて、ネストされたリソースを反映するようにShow
を更新します。 ファイルの最後の2行を次のように変更します。
〜/sharkapp/app/views/posts/edit.html.erb
. . . <%= link_to 'Show', [@shark, @post] %> | <%= link_to 'Back', shark_posts_path(@shark) %>
ファイルを保存して閉じます。
次に、show
テンプレートを開きます。
nano app/views/posts/show.html.erb
ファイルの下部にあるEdit
およびBack
パスを次のように編集します。
〜/sharkapp/app/views/posts/edit.html.erb
. . . <%= link_to 'Edit', edit_shark_post_path(@shark, @post) %> | <%= link_to 'Back', shark_posts_path(@shark) %>
終了したら、ファイルを保存して閉じます。
最後のステップとして、サメのshow
ビューを更新して、個々のサメの投稿が表示されるようにします。 今すぐそのファイルを開きます:
nano app/views/sharks/show.html.erb
ここでの編集には、フォームにPosts
セクションを追加し、ファイルの下部にAdd Post
リンクを追加することが含まれます。
特定のサメのFacts
の下に、このサメに関連付けられた投稿のコレクション内の各インスタンスを反復処理する新しいセクションを追加し、各投稿のbody
を出力します。
フォームのFacts
セクションの下、およびファイルの下部にあるリダイレクトの上に次のコードを追加します。
〜/ sharkapp / app / views / sharks / show.html.erb
. . . <p> <strong>Facts:</strong> <%= @shark.facts %> </p> <h2>Posts</h2> <% for post in @shark.posts %> <ul> <li><%= post.body %></li> </ul> <% end %> <%= link_to 'Edit', edit_shark_path(@shark) %> | . . .
次に、新しいリダイレクトを追加して、ユーザーがこの特定のサメの新しい投稿を追加できるようにします。
〜/ sharkapp / app / views / sharks / show.html.erb
. . . <%= link_to 'Edit', edit_shark_path(@shark) %> | <%= link_to 'Add Post', shark_posts_path(@shark) %> | <%= link_to 'Back', sharks_path %>
編集が終了したら、ファイルを保存して閉じます。
これで、アプリケーションのモデル、コントローラー、およびビューに変更を加えて、投稿が常に特定のサメに関連付けられるようにしました。 最後のステップとして、Post
モデルにいくつかの検証を追加して、データベースに保存されるデータの一貫性を保証できます。
ステップ5—検証の追加とアプリケーションのテスト
How To Build Ruby onRailsアプリケーションのステップ5で、Shark
モデルに検証を追加して、に保存されるデータの均一性と一貫性を確保しました。 sharks
データベース。 posts
データベースの保証も確実にするために、同様の手順を実行します。
Post
モデルが定義されているファイルを開きます。
nano app/models/post.rb
ここでは、投稿が空白にならないようにし、他のユーザーが投稿した可能性のあるコンテンツと重複しないようにします。 これを実現するには、ファイルに次の行を追加します。
〜/ sharkapp / app / models / post.rb
class Post < ApplicationRecord belongs_to :shark validates :body, presence: true, uniqueness: true end
編集が終了したら、ファイルを保存して閉じます。
この最後の変更が行われると、移行を実行してアプリケーションをテストする準備が整います。
まず、移行を実行します。
rails db:migrate
次に、サーバーを起動します。 ローカルで作業している場合は、次のコマンドを実行して作業できます。
rails s
開発サーバーで作業している場合は、代わりに次のコマンドを実行します。
rails s --binding=your_server_ip
http://localhost:3000
またはhttp://your_server_ip:3000
でアプリケーションのルートに移動します。
前提条件となるRailsプロジェクトのチュートリアルでは、 GreatWhiteサメのエントリを追加および編集する手順を説明しました。 これ以上サメを追加していない場合、アプリケーションのランディングページは次のようになります。
グレートホワイトの名前の横にある表示をクリックします。 これにより、このサメのshow
ビューに移動します。 サメの名前とその事実、およびコンテンツのないPostsヘッダーが表示されます。 フォームのこの部分に入力する投稿を追加しましょう。
投稿ヘッダーの下にある投稿の追加をクリックします。 これにより、投稿index
ビューが表示され、新しい投稿を選択できます。
Ruby on Railsアプリケーションの構築方法のステップ6で導入した認証メカニズムのおかげで、そのステップで作成したユーザー名とパスワードで認証を求められる場合があります、新しいセッションを作成したかどうかによって異なります。
新しい投稿をクリックすると、投稿new
テンプレートが表示されます。
Body フィールドに、「これらのサメは怖いです!」と入力します。
投稿の作成をクリックします。 このサメに属するすべての投稿のindex
ビューにリダイレクトされます。
投稿リソースが機能しているので、データ検証をテストして、必要なデータのみがデータベースに保存されていることを確認できます。
index
ビューで、新しい投稿をクリックします。 新しいフォームのBodyフィールドに、「これらのサメは怖いです!」と入力してみてください。 また:
投稿の作成をクリックします。 次のエラーが表示されます。
戻るをクリックして、メインの投稿ページに戻ります。
他の検証をテストするには、新しい投稿をもう一度クリックします。 投稿を空白のままにして、投稿の作成をクリックします。 次のエラーが表示されます。
ネストされたリソースと検証が適切に機能することで、今後の開発の開始点として使用できるRailsアプリケーションが機能するようになります。
結論
Railsアプリケーションを配置すると、他のフロントエンドコンポーネントのスタイリングや開発などに取り組むことができます。 ルーティングとネストされたリソースについて詳しく知りたい場合は、Railsドキュメントから始めるのが最適です。
フロントエンドフレームワークをアプリケーションに統合する方法の詳細については、Reactフロントエンドを使用してRubyonRailsプロジェクトをセットアップする方法を参照してください。