20220114のRailsに関する記事は10件です。

Railsでコメント機能のajax化

コメント機能のajax化 前回のajax化の記事にてどんなものかある程度理解したので、この記事ではお気に入りボタンの実装を例としてしたが、今回はコメント機能の投稿と削除のajax化の備忘録として記載。 手順 ①コントローラーの修正 ②remote: trueの追加やclass、idの指定 ③js.erbファイルの追加 ①コントローラーの修正 redirect先を削除 修正前comments_controller.rb class CommentsController < ApplicationController def create comment = current_user.comments.build(comment_params) if comment.save redirect_to board_path(comment.board), success: t('defaults.message.created', item: Comment.model_name.human) else redirect_to board_path(comment.board), danger: t('defaults.message.not_created', item: Comment.model_name.human) end ↓このように修正。 修正後comments_controller.rb class CommentsController < ApplicationController def create @comment = current_user.comments.build(comment_params) @comment.save end ②remote: trueの追加やclass、idの指定 コメントフォームにid:'new_comment'、 テキストエリアにid:"js-new-comment-body"を追加。 またform_withからlocal: trueを削除。form_withは元からremote :tureとなっているのでわざわざ新たに記入する必要はない。 エラーメッセージはformではなく後に出てくるjs.erbファイルに記載する。 form.html.rb <%= form_with model: comment,url: [board, comment],id:'new_comment' do |f|%> <div class="form-group"> <%= f.label :body%> <%= f.text_area :body,class:"form-control mb-3",id:"js-new-comment-body",row:4,placeholder: "コメント"%> </div> <%= f.submit t('defaults.post'),class:"btn btn-primary"%> <%end%> 削除ボタンにclass: 'js-delete-comment-button'とremote: trueを追加。 delete_button.rb <%= link_to comment_path(comment), class: 'js-delete-comment-button', method: :delete, data: { confirm: "コメントを削除します。よろしいですか?" }, remote: true do %> <%= icon 'fa', 'trash' %> <% end %> ③js.erbファイルの追加 コメントviewファイル直下にcreate.js.erbとdestroy.js.erbを作成。 create.js.erb # ↓既に表示されているエラーメッセージがあった場合は削除する $("#error_messages").remove() # ↓コメント作成処理の結果によって処理を分岐 <% if @comment.errors.present? %>     # ↓エラーがある、処理失敗時にはエラーメッセージのパーシャルを表示 $("#new_comment").prepend("<%= j(render('shared/error_messages', object: @comment)) %>") <% else %>     # エラーがない、処理成功時には作成されたコメント内容をHTML要素として追加する $("#js-table-comment").prepend("<%= j(render('comments/comment', comment: @comment)) %>")      # ↓コメント入力フォームのテキストは表示する必要がないので、空文字に置き換えて内容をクリアにする $("#js-new-comment-body").val('') <% end %> destroy.js.erb $("tr#comment-<%= @comment.id %>").remove()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【ざっと確認】RailsのRoutingで見かけるscope / namespace / module / action / asの意味

はじめに routesの読み方で不安になった時用の書き残しです。 scope / namespace / moduleの根本の動作が知りたい方はこちらが参考になります。 https://qiita.com/ryosuketter/items/9240d8c2561b5989f049 まとめ scope scopeに指定した文字がurlにのみ影響する module moduleに指定した文字がファイル構成にのみ影響する namespace namespaceに指定した文字がurl、ファイル構成、Prefixの全てに影響する as リソースの名前をオーバーライドする
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】Routingのカンペ(scope / namespace / module / action / as / コロン / constraintsの意味)

はじめに routesの読み方で不安になった時用のカンペです。 scope / namespace / moduleの根本の動作が知りたい方はこちらが参考になります。 https://qiita.com/ryosuketter/items/9240d8c2561b5989f049 目次 まとめ scope module namespace as コロン constraints まとめ scope scopeに指定した文字がurlにのみ影響する module moduleに指定した文字がファイル構成にのみ影響する namespace namespaceに指定した文字がurl、ファイル構成、Prefixの全てに影響する as Prefixをオーバーライドする コロン 動的に変化する部分 constraints コロン部分の制約を設定
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker compose環境のrailsでDB関連のエラーが出たら確認することまとめ

環境 docker compose mysql rails6 rails初心者が色々迷走しているうちに様々なエラーに出会ったのでまとめてみます。 エラー データベースがない時に出るエラーです。 error.rb ActiveRecord::NoDatabaseError: Unknown database 対応 データベースがあるかを確認します。 checkdb.sh #execコマンドでrailsコンテナの中に入ります。 $ docker exec -it xxxxxxxxxx bash #railsコンテナの中からmysqlコンテナに接続しつつmysqlを立ち上げます。 root@xxxxxxxxxx:/app# mysql -u root -p -h db #ここでmysqlが立ち上がらない場合そもそもdockerコンテナ同士の通信がうまく行っていないので下の「dockerコンテナ間の通信を確認する」を見てください。 #mysqlが立ち上がった場合はshow databasesでデータベースがあるか確認します。データベース名はrailsアプリの/config/database.ymlでdatabase: rails_sample_dvなどと記載されています。 MySQL [(none)]> show databases; #データベースがなかった場合は作成します。 MySQL [(none)]>exit root@xxxxxxxxxx:/app# rails db:create root@xxxxxxxxxx:/app# rails db:migrate これでデータベースが作成されるので0.0.0.0:3000などでアクセスができるようになります。 dockerコンテナ同士がつながっていなそうな場合 docker-compose.ymlの設定を確認します。 以下db接続関連の項目のみを書き出してみます。 これらがない場合は書き足してみてdockerを再構築 (環境によってはimage、volumeを削除してdocker compose build --no-cacheなどとすると確実かもしれません。) してみて再度ウェブコンテナからmysqlに接続できるかを確認します。 docker-compose.yml version: "3" services: app: depends_on: - mysql mysql: volumes: - mysql-volume:/var/lib/mysql environment: - MYSQL_ALLOW_EMPTY_PASSWORD=yes ports: - "3306:3306" volumes: mysql-volume: railsのdatabase.ymlの記述が間違っていたときのエラー 自分の場合は以下のエラーがブラウザでアクセスした時に出ました。 error1.rb ActiveRecord::ConnectionNotEstablished No connection pool for 'ActiveRecord::Base' found. error2.rb Puma caught this error: Cannot load database configuration: そしてその状態でrails consoleを立ち上げようとして以下のエラーに遭遇 error3.sh webapp/config/database.yml:33:in `<main>': Cannot load database configuration: undefined method `[]' for nil:NilClass (NoMethodError) ちなみにその時のdatabase.ymlは以下 database.yml default: &default adapter: mysql2 encoding: utf8mb4 pool: 5 timeout: 3306 host: mysql development: <<: *default username: root host: mysql database: rails_sample_dv socket: /tmp/mysql.sock # test: # <<: *default # username: root # host: <%= ENV['DB_HOST'] %> # database: rails_sample_dv # socket: /tmp/mysql.sock # production: # <<: *default # username: <%= Rails.application.credentials.db[:user] %> # host: <%= Rails.application.credentials.db[:host] %> # password: <%= Rails.application.credentials.db[:password] %> # database: <%= Rails.application.credentials.db[:name] %> これはなぜかコメントアウトしている行が読み込まれているようで 以下のようにコメントアウトしている部分を削除したらとりあえずエラーは解消されました。 database.yml default: &default adapter: mysql2 encoding: utf8mb4 pool: 5 timeout: 3306 host: mysql development: <<: *default username: root host: mysql database: rails_sample_dv socket: /tmp/mysql.sock master.key、credentials.yml.encを作り直してみる railsアプリの/configディレクトリにmaster.key、credentials.yml.encというファイルがあります。 これらがなかったり、なんらかの影響で変更されたりした場合railsアプリが立ち上がらない場合があります。 そんな時は念の為2つのファイルをバックアップしてから 作成し直すことでアプリが立ち上がる場合もあります。 作成し直す際は前述同様docker execコマンドでrailsコンテナにログインしてから以下のコマンドで再生成します。 recreate.sh EDITOR=vim rails credentials:edit 場合によってはsudoをつけたほうが良いかもしれません。 そもそもmaster.key、credentials.yml.encとは? いわゆるサーバで設定する環境変数をrails内で設定できるという仕組みで master.key(秘密鍵)、credentials.yml.enc(公開鍵)といった具合に 1組の対になっています。 ですから何らかの拍子で一つが変わったりする場合エラーになります。 またmaster.keyは必ず.gitignoreなどに記載し、公開されないように デプロイツールに登録しなければなりません。 番外編|コンテナが立ち上がらない railsのWebサーバが立ち上がっていない状態です。 docker.sh $ docker compose up -d $ docker container ls cfxxxxxxa776 mysql:5.7 "docker-entrypoint.s…" 1 minutes ago Up 1 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp webapp-db-1 対応方法 /tmp/pids/server.pid というファイルを削除しコンテナを再度立ち上げると無事ウェブサーバが立ち上がりました。 これはrails特有のお作法でよくある原因とのことでした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】メソッド名を付けるときに気をつけること

最近、1つのメソッドで色々なことをしてしまってるメソッドのリファクタリングをしていて、 その過程で処理ごとにメソッドに切り出すことが多く、 メソッド名の付け方で迷うことがあったのでまとめてみる。 オブジェクトを別の形に変換するメソッド名はto_hogeにする # hashにして返すメソッド # 悪くはない例 def convert_to_hash end # より良い例 def to_hash end 否定形のメソッド名はなるべく作らない 判定が複雑になると可読性が下がってしまうこともある。 否定形のメソッドを作りたくなったときは、逆の意味(肯定)のメソッドを作って!hogeの形にして使う。 # 良くない例 book.not_published? # 良い例 !book.published? 判定形のメソッドの末尾には疑問符?をつける trueかfalseを返すメソッドの末尾にだけ「?」をつける。それ以外にはつけない。 shop.open? メソッド名に疑問符をつけられるのはRubyだけらしい。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

{Rails}ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)が出た場合の対処法

①やりたいこと MySQLにログインしたい。 Modelを作成し、rails db:migrateを実行した後の出来事でした。(この2つは問題なく実行できました) ②エラー内容 % sudo mysql -u root Password: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) ちなみにsudo mysql -u rootと打つとEnter password:と出てくるので、パスワードを打った後に出てきたのがこのエラー文です。 ③原因 ④解決策 下記の記事を参考にしました。 https://ja.getdocs.org/mysql-error-1-45-28-access-denied-for-user-rootlocalhost-using-password-no/ 引用すると >ユーザ ‘root’は、MySQLサーバにログインするためのパスワードが必要です。 ** これを解決するには、MySQLサーバーに接続する際にパスワードに -pフラグを付けてください。 とのことなのでmysql -u root -pでもう一度実行したら、無事ログインできました。(sudo mysql -u root -pでもできますが、パスワードを2回打つことになるのでsudoはなくてもいいです。) あとがき:-p(password?)を付けるのと付けないのでは何が違うのか、わかる方いればご教授いただきたいです。 開発環境 mac OS バージョン11.6 Rails 6.1.4.4 Ruby 3.0.3 MYSQL 0.5 エディタ VScode
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【2022年最新】Rails6にBootstrap5を導入する方法

※ 本記事はRails6でBootstrap5を導入したい方向けの記事です! ※ Rails5やBootstrap4など、バージョン違いのものを導入する場合とは手順が異なります! 開発環境&前提条件 Ruby 3.0.2 Rails 6.1.4.4 導入したBootstrap 5.1.3 Rails6でrails newしてある状態 Bootstrap5のインストール terminal % yarn add bootstrap 上記コマンドでBootstrapの最新バージョンがインストールされます! バージョンを指定する場合? terminal % yarn add bootstrap@バージョン番号 ドロップダウンなどのポップアップ要素をいい感じにしてくれるpopper.jsもインストールします! terminal % yarn add @popperjs/core application.html.erbに追記 app/views/layouts/application.html.erb <!DOCTYPE html> <html> <head> <title>Title</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <%= csrf_meta_tags %> <%= csp_meta_tag %> <% stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> <%# ここを追加? %> <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>         <%# ここを追加? %> </head> <body> <%= yield %> </body> </html> 上記の通り、stylesheet_pack_tagの一文を追加します! application.scssの作成・追記 Bootstrapを読み込むためのファイルを作成します! app/javascript配下に、stylesheetsフォルダを作成、そのフォルダの中にapplication.scssファイルを作成します! terminal % mkdir ./app/javascript/stylesheets % touch ./app/javascript/stylesheets/application.scss 作成したapplication.scssに以下を追記します! app/javascript/stylesheets/application.scss @import "~bootstrap/scss/bootstrap.scss"; application.jsに追記 上記application.scssを読み込む記述をapplication.jsに追記します! app/javascript/packs/application.js import Rails from "@rails/ujs" import Turbolinks from "turbolinks" import * as ActiveStorage from "@rails/activestorage" import "channels" // ここを追加? import "bootstrap"; import "../stylesheets/application.scss"; // ここを追加? Rails.start() Turbolinks.start() ActiveStorage.start() これでBootstrap5の導入は完了です! あとはいつも通りBootstrapクラスの指定をしてあげれば適応されます? 最後に Rails6にBootstrap5を導入する記事が少なかったので本記事を作成しました。 本記事がBootstrapの導入で悩んでいる方に届けば幸いです?‍♂️
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

{VScode} 「Implicit keys needs to be on a single line」と出た場合

VScodeでdatabase.ymlをいじっていると、下の「問題」となっているところに「Implicit keys needs to be on a single line」と出ました。 何やら問題が発生しているらしく、その対象の文が赤線で引かれています。(画像) https://gyazo.com/e934bd8d247577458c145c7bf9b64fb1 よくわからなかったので、この状態のままrails sコマンドでページを開こうとしました。すると、、 https://gyazo.com/b6efd3ee3abadd7aa9435a93c209e2a9 何やらエラーが出て、ページが表示されません。 Please note that YAML must be consistently indented using spaces. Tabs are not allowed. ↑ Google先生に和訳してもらうと、「YAMLはスペースを使用して一貫してインデントする必要があることに注意してください。 タブは許可されていません。」とのこと。 非常に単純な問題でしたが、単純ゆえにハマるとなかなかわからなかったりするんですよね〜。 https://gyazo.com/409e56275d445c48216d8630e4183d89 言われたとおりインデントして、再度試したらちゃんと開けました! 開発環境 mac OS バージョン11.6
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

カラム型の種類

型 意味 string 文字列(1〜255文字) text 長い文字列(1〜4294967296文字) integer 整数(4バイト) bigint 整数(8バイト) float 浮動小数 decimal 精度の高い小数 numeric 数値 datetime 日時 timestamp タイムスタンプ time 時間 date 日付 binary バイナリデータ boolean 真偽値型
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GraphQL RubyのDataloaderを使ってみる

GraphQL Rubyを使っているときにSQLのN+1問題を解決するためにバッチロードを利用すると思います。 有名なgemとしては GraphQL::Batch や BatchLoader、 Dataloaderなどがあります。 個人的には使ったことがあるのはDataloaderなのですが、2018年から更新されていないようなのと、去年GraphQL Ruby自体にDataloaderが入ったので今回はこちらを触ってみました。 GraphQL::Dataloader の概要 ドキュメントはこちらです。 GraphQL::Dataloaderはデータベースアクセスを効率的に行うためのツールで、RubyのFiberを使っており、Ruby 3のノンブロッキングFiberもサポートしているようです。影響を受けたものとしては以下2つが挙げられています。 https://github.com/bessey/graphql-fiber-test/tree/no-gem-changes https://github.com/shopify/graphql-batch Dataloader vs. GraphQL-Batchでも、GraphQL-Batchなどの他のローダーはPromiseを使っている一方で、このDataloaderはFiberを使っているということが特徴として挙げられています。committerのRobert Mosolgoによると、Promiseを使うと複雑になりやすいところを、Rubyにもともと備わっている機能であるFiberを使うことで、他に何も使わずとも並列I/Oが使えるというところで選んだようです。 前提 graphql v1.13.2 rails v7.0.0 前準備 サンプルのデータをもとに検証してみます。 シンプルにUser, Aritcle, Likeの3つのテーブルを作ります。 class User < ApplicationRecord has_many :articles, foreign_key: 'author_id' end class Article < ApplicationRecord belongs_to :author, class_name: 'User' has_many :likes end class Like < ApplicationRecord belongs_to :article, validate: true belongs_to :user, validate: true end フィールドはこんな感じです。 module Types class UserType < Types::BaseObject field :id, ID, null: false field :name, String, null: false field :email, String, null: false field :articles, Types::ArticleType.connection_type, null: false end end module Types class ArticleType < Types::BaseObject field :id, ID, null: false field :title, String, null: false field :body, String, null: false field :author, Types::UserType, null: false field :liked, Types::LikeConnection, null: false, method: :likes end end module Types class LikeType < Types::BaseObject field :id, ID, null: false field :user, Types::UserType, null: false field :article, Types::ArticleType, null: false field :liked_at, Int, null: false, method: :created_at end end 今回欲しいクエリはこんな感じで、現在のユーザーが投稿した記事一覧とその記事にLikeしたユーザーの一覧を取得します。一部ページネーションでConnectionを使っています。 query { currentUser { name articles { edges { node { title body liked { count edges { node { user { name } } } } } } } } } ダミーデータも生成しておく 取得するデータを生成しておきます。 クエリの取得結果はこのようになりました。 { "data": { "currentUser": { "name": "test_user1", "articles": { "edges": [ { "node": { "title": "first article", "body": "first article body", "liked": { "count": 4, "edges": [ { "node": { "user": { "name": "test_user2" } } }, { "node": { "user": { "name": "test_user3" } } }, { "node": { "user": { "name": "test_user4" } } }, { "node": { "user": { "name": "test_user5" } } } ] } } }, { "node": { "title": "second article", "body": "second article body", "liked": { "count": 1, "edges": [ { "node": { "user": { "name": "test_user2" } } } ] } } }, { "node": { "title": "third article", "body": "third article body", "liked": { "count": 2, "edges": [ { "node": { "user": { "name": "test_user3" } } }, { "node": { "user": { "name": "test_user4" } } } ] } } }, { "node": { "title": "forth article", "body": "forth article body", "liked": { "count": 0, "edges": [] } } }, { "node": { "title": "fifth article", "body": "fifth article body", "liked": { "count": 1, "edges": [ { "node": { "user": { "name": "test_user5" } } } ] } } } ] } } } } まずクエリを投げてみる このまま素直にクエリを投げると、素直にN+1が発生してくれるのでこれを解消していきます。 User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] Article Load (0.2ms) SELECT "articles".* FROM "articles" WHERE "articles"."author_id" = ? LIMIT ? [["author_id", 1], ["LIMIT", 20]] Like Load (0.1ms) SELECT "likes".* FROM "likes" WHERE "likes"."article_id" = ? LIMIT ? [["article_id", 1], ["LIMIT", 20]] Like Load (0.1ms) SELECT "likes".* FROM "likes" WHERE "likes"."article_id" = ? LIMIT ? [["article_id", 2], ["LIMIT", 20]] Like Load (0.2ms) SELECT "likes".* FROM "likes" WHERE "likes"."article_id" = ? LIMIT ? [["article_id", 3], ["LIMIT", 20]] Like Load (0.2ms) SELECT "likes".* FROM "likes" WHERE "likes"."article_id" = ? LIMIT ? [["article_id", 4], ["LIMIT", 20]] Like Load (0.5ms) SELECT "likes".* FROM "likes" WHERE "likes"."article_id" = ? LIMIT ? [["article_id", 5], ["LIMIT", 20]] User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]] User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]] User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]] User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]] User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]] User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]] Dataloaderの導入 新規プロジェクトでrails generate graphql:installした場合はすでに有効化されていますが、schemaに以下の行を追加するだけです。 class MySchema < GraphQL::Schema # ... + use GraphQL::Dataloader end シングルレコードを取得 まずはbelongs_toの関係になっている、like.user部分のシングルレコードの取得部分からから準備します。 実装するものとしては、 Source resolverのメソッド の2つです。 說明する前に先にコードを載せます。 こちらはほぼドキュメントに乗っているサンプルそのままです。 app/graphql/sources/user_by_id.rb module Sources class UserById < GraphQL::Dataloader::Source def initialize @model_class = ::User end def fetch(ids) records = @model_class.where(id: ids) ids.map { |id| records.find { |r| r.id == id.to_i } } end end end app/graphql/types/like_type.rb module Types class LikeType < Types::BaseObject field :user, Types::UserType, null: false + def user + dataloader.with(::Sources::UserById).load(object.user_id) + end end end これによって、Userの取得が以下のように1つのクエリで完結します。 User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (?, ?, ?, ?) [["id", 2], ["id", 3], ["id", 4], ["id", 5]] 解説 まずSourceについてです。 Sourceはバッチロードする処理を記述するクラスで、GraphQL::Dataloader::Sourceを継承し、fetchメソッドを実装します。 このSourceはGraphQL::Dataloaderによってインスタンス生成され、fetchメソッドが呼ばれるのですが、引数としては取得するためのkey(今回でいうとids)が渡されます。今回はこのkeyからUserのデータを取得します。 返り値は渡された引数のkeyと同じ順番でオブジェクトを返す必要があります。 そしてresolver側では以下のように取得します。 def user dataloader.with(::Sources::UserById).load(object.user_id) end loadで裏側でFiberのキューに入れて遅延ロードを行っているようです。この例でいくとobject.user_idがSourceのfetchメソッドの引数として渡されます。 マルチレコードを取得 こちらも先にコードを載せます。 基本的にはシングルレコードとあまり変わりません。 app/graphql/sources/likes_by_user_id.rb module Sources class LikesByUserId < GraphQL::Dataloader::Source def initialize @model_class = ::Like end def fetch(keys) records = @model_class.where(article_id: keys) .group_by { |record| record.article_id } keys.map { |key| records[key] || [] } end end end app/graphql/types/article_type.rb module Types class ArticleType < Types::BaseObject field :liked, Types::LikeConnection, null: false + def liked + dataloader.with(::Sources::LikesByUserId).load(object.id) + end end end 少し変わったのはfetchメソッドくらいですね。 こちらは1つのkeyに対して複数レコードが返ってくる可能性があるのでgroup_byをしています。 返り値は同様にkeyの順番に合わせて配列を返しています。 これだけでマルチレコードも遅延ロードができました。 結果以下のようになり、かなり効率的なクエリになりました。 User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] Article Load (0.1ms) SELECT "articles".* FROM "articles" WHERE "articles"."author_id" = ? LIMIT ? [["author_id", 1], ["LIMIT", 20]] Like Load (0.1ms) SELECT "likes".* FROM "likes" WHERE "likes"."article_id" IN (?, ?, ?, ?, ?) [["article_id", 1], ["article_id", 2], ["article_id", 3], ["article_id", 4], ["article_id", 5]] User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (?, ?, ?, ?) [["id", 2], ["id", 3], ["id", 4], ["id", 5]] まだ分かっていないこと GraphQL::Batchなどに比べるとGraphQL Dataloaderはまだ導入されたばかりです。そのため、今回はかなりシンプルなものしか試していないので、実際の運用で出てくるような複雑なものまで実用に耐えられるのかは不明です。 また、ドキュメントを見ていると1Source 1クラスで処理は似たものでもクラスが増えていきそうな印象でした。Sourceが増えてきたときに効率的に実装して管理できるかはまだ不明です。 最後に GraphQL::Batchなど他のGemはまだ触っていないのですが、GraphQL Rubyに入っているというだけあって、導入はめちゃくちゃ楽でした。お手軽に使いたいのであればとてもいいと思います。 また他のLoaderも触ってみて比較したいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む