序章

Ruby on Rails プロジェクトで作業している場合、要件には、ビューテンプレートによって生成されたHTMLとの対話性が含まれる場合があります。 その場合、この対話性を実装する方法についていくつかの選択肢があります。

たとえば、ReactEmberのようなJavaScriptフレームワークを実装できます。 要件にクライアント側での状態の処理が含まれている場合、またはサーバーへの頻繁なクエリに関連するパフォーマンスの問題が懸念される場合は、これらのフレームワークのいずれかを選択するのが理にかなっている場合があります。 多くのシングルページアプリケーション(SPA)は、このアプローチを採用しています。

ただし、クライアント側で状態と頻繁な更新を管理するフレームワークを実装する際に留意すべきいくつかの考慮事項があります。

  1. JavaScriptの解析、JSONのフェッチとHTMLへの変換などの読み込みと変換の要件により、パフォーマンスが制限される可能性があります。
  2. フレームワークへのコミットメントには、特に小規模なJavaScriptの拡張機能を探している場合に、特定のユースケースで必要とされるよりも多くのコードを記述することが含まれる場合があります。
  3. クライアント側とサーバー側の両方で状態管理を行うと、作業が重複し、エラーの表面積が増える可能性があります。

別の方法として、 Basecamp のチーム(Railsを作成したのと同じチーム)が Stimulus.js を作成しました。これは、「既存のHTML用の控えめなJavaScriptフレームワーク」と説明されています。 」 Stimulusは、サーバー側で生成されたHTMLを操作することにより、最新のRailsアプリケーションを強化することを目的としています。 状態はDocumentObject Model(DOM)に存在し、フレームワークはDOM内の要素やイベントと対話するための標準的な方法を提供します。 Turbolinks (デフォルトではRails 5+に含まれています)と連携して動作し、明確に定義された目的に限定され、スコープが設定されたコードでパフォーマンスとロード時間を改善します。

このチュートリアルでは、Stimulusをインストールして使用し、サメに関する情報を読者に提供する既存のRailsアプリケーションを構築します。 このアプリケーションにはすでにサメのデータを処理するためのモデルがありますが、個々のサメに関する投稿用のネストされたリソースを追加して、ユーザーがサメに関する一連の考えや意見を構築できるようにします。 この部分は、JavaScriptを使用してページ上の投稿の位置と外観を操作することを除いて、 RubyonRailsアプリケーションのネストされたリソースを作成する方法とほぼ並行して実行されます。 また、ポストモデル自体を構築するために少し異なるアプローチを取ります。

前提条件

このチュートリアルに従うには、次のものが必要です。

  • 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—ネストされたモデルの作成

最初のステップは、ネストされたPost モデルを作成することです。これを、既存のSharkモデルに関連付けます。 これを行うには、モデル間にActive Recordアソシエーションを作成します。投稿は特定のサメに属し、各サメは複数の投稿を持つことができます。

開始するには、前提条件でRailsプロジェクト用に作成したsharkappディレクトリに移動します。

  1. cd sharkapp

Postモデルを作成するには、 railsgenerateコマンドとmodelジェネレーターを使用します。 次のコマンドを入力して、モデルを作成します。

  1. rails generate model Post body:text shark:references

body:textでは、Railsにbodyフィールドをpostsデータベーステーブル(Postモデルにマップするテーブル)に含めるように指示しています。 :referencesキーワードも含まれています。これはSharkモデルとPostモデル間の関連付けを設定します。 具体的には、これにより、sharksデータベースの各サメエントリを表す外部キーpostsデータベースに追加されます。

コマンドを実行すると、Railsがアプリケーション用に生成したリソースを確認する出力が表示されます。 先に進む前に、データベース移行ファイルをチェックして、モデルとデータベーステーブルの間に現在存在する関係を確認できます。 次のコマンドを使用してファイルの内容を確認し、ここに表示されているものを自分の移行ファイルのタイムスタンプに置き換えてください。

  1. cat db/migrate/20190805132506_create_posts.rb

次の出力が表示されます。

Output
class 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
Output
class Post < ApplicationRecord belongs_to :shark end

belongs_toアソシエーションは、宣言モデルの単一インスタンスが名前付きモデルの単一インスタンスに属するモデル間の関係を設定します。 私たちのアプリケーションの場合、これは単一の投稿が単一のサメに属することを意味します。

RailsはすでにPostモデルでbelongs_toの関連付けを設定していますが、Sharkモデルでもhas_manyの関連付けを指定する必要があります。正しく機能するためのその関係。

has_manyの関連付けをSharkモデルに追加するには、nanoまたはお気に入りのエディターを使用してapp/models/shark.rbを開きます。

  1. 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+XYENTERの順に押してください。

これで投稿用にモデルが生成されましたが、データベース内のデータと生成されてユーザーに表示されるHTMLを調整するためのコントローラーも必要になります。

ステップ2—ネストされたリソースのコントローラーを作成する

投稿コントローラーを作成するには、アプリケーションのメインルーティングファイルにネストされたリソースルートを設定し、コントローラーファイル自体を作成して、特定のアクションに関連付けるメソッドを指定する必要があります。

まず、config/routes.rbファイルを開いて、リソースの豊富なルート間の関係を確立します。

  1. nano config/routes.rb

現在、ファイルは次のようになっています。

〜/sharkapp/config/routes.rb
Rails.application.routes.draw do
  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

編集が終了したら、ファイルを保存して閉じます。

次に、コントローラー用にapp/controllers/posts_controller.rbという名前の新しいファイルを作成します。

  1. nano app/controllers/posts_controller.rb

このファイルでは、個々の投稿を作成および破棄するために使用するメソッドを定義します。 ただし、これはネストされたモデルであるため、特定の投稿を特定のサメに関連付けるために使用できるローカルインスタンス変数@sharkも作成する必要があります。

まず、PostsControllerクラス自体を、特定のサメを参照できるget_sharkpost_paramsの2つのprivateメソッドとともに作成できます。 、paramsメソッドを介してユーザーが送信した情報にアクセスできます。

次のコードをファイルに追加します。

〜/sharkapp/app/controllers/posts_controller.rb
class PostsController < ApplicationController
  before_action :get_shark 

  private

  def get_shark
    @shark = Shark.find(params[:shark_id])
  end

  def post_params
    params.require(:post).permit(:body, :shark_id)
  end
end

これで、:shark_idキーと、ユーザーが投稿を作成するために入力するデータを使用して、投稿が関連付けられる特定のサメのインスタンスを取得するメソッドができました。 これらのオブジェクトは両方とも、投稿の作成と破棄を処理するために定義するメソッドで使用できるようになります。

次に、privateメソッドの上に、次のコードをファイルに追加して、createおよびdestroyメソッドを定義します。

〜/sharkapp/app/controllers/posts_controller.rb
. . .
  def create
    @post = @shark.posts.create(post_params)
  end
      
  def destroy
    @post = @shark.posts.find(params[:id])
    @post.destroy   
  end
. . .

これらのメソッドは、@postインスタンスを特定の@sharkインスタンスに関連付け、サメと投稿。 findcreateなどのメソッドを使用すると、特定のサメに関連付けられた投稿のコレクションをターゲットにすることができます。

完成したファイルは次のようになります。

〜/sharkapp/app/controllers/posts_controller.rb
class PostsController < ApplicationController
  before_action :get_shark 

  def create
    @post = @shark.posts.create(post_params)
  end
      
  def destroy
    @post = @shark.posts.find(params[:id])
    @post.destroy   
  end

  private

  def get_shark
    @shark = Shark.find(params[:shark_id])
  end

  def post_params
    params.require(:post).permit(:body, :shark_id)
  end
end

編集が終了したら、ファイルを保存して閉じます。

コントローラとモデルを配置したら、ビューテンプレートと、アプリケーションで生成されたHTMLをどのように整理するかについて考え始めることができます。

ステップ3—パーシャルを使用したビューの再編成

Postモデルとコントローラーを作成したので、Railsの観点から最後に考えるのは、ユーザーがサメに関する情報を表示および入力できるようにするビューです。 ビューは、Stimulusとの双方向性を構築する機会もあります。

このステップでは、Stimulusでの作業の開始点となる、ビューとパーシャルをマップします。

投稿および投稿に関連付けられたすべてのパーシャルのベースとして機能するビューは、sharks/showビューです。

ファイルを開きます。

  1. nano app/views/sharks/show.html.erb

現在、ファイルは次のようになっています。

〜/ sharkapp / app / views / sharks / show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <strong>Name:</strong>
  <%= @shark.name %>
</p>

<p>
  <strong>Facts:</strong>
  <%= @shark.facts %>
</p>

<%= link_to 'Edit', edit_shark_path(@shark) %> |
<%= link_to 'Back', sharks_path %>

Postモデルを作成したとき、投稿のビューはsharks/showビューで処理するため、生成しないことを選択しました。 したがって、このビューでは、最初に対処するのは、新しい投稿に対するユーザー入力を受け入れる方法と、ユーザーに投稿を提示する方法です。

注:このアプローチの代替方法については、 RubyonRailsアプリケーションのネストされたリソースを作成する方法を参照してください。投稿コントローラーで定義されているRead、Update、Delete