という挙動に遭遇し、なんでだと途方に暮れていたら、以下が原因だった・・。
公式のRubyのDockerイメージのbundlerの挙動 https://blog.freedom-man.com/ruby-docker-bundler
という挙動に遭遇し、なんでだと途方に暮れていたら、以下が原因だった・・。
公式のRubyのDockerイメージのbundlerの挙動 https://blog.freedom-man.com/ruby-docker-bundler
let mut vec = vec![1,2,3,1,2,3]; vec.sort(); // これが無いと重複排除されない vec.dedup(); println!("{:?}", vec); // [1, 2, 3]
# == Schema Information # # Table name: cards # # id :bigint not null, primary key # remembered :boolean not null # card_set_id :bigint not null # created_at :datetime not null # updated_at :datetime not null # class Card < ApplicationRecord belongs_to :card_set end # == Schema Information # # Table name: card_sets # # id :bigint not null, primary key # name :string not null # created_at :datetime not null # updated_at :datetime not null # class CardSet < ApplicationRecord has_many :cards end
コントローラーで以下のように実装すると(1)(2)両方で、クエリが発行されてN+1状態になってしまう。
def test @card_sets = CardSet.all @card_sets.each do |card_set| card_set.cards.size # (1) card_set.cards.where(remembered: true).size # (2) end end
そこで以下のようにカードセットを取得するときに eager_load
すると上記の (1) でキャッシュが効き、クエリが発行されなくなる。
@card_sets = CardSet.all.eager_load(:cards)
しかし、(2)ではまだクエリが都度発行されてしまう。これは where メソッドが都度SQLを発行してしまうことによる。Ruby上では各カードの関連データをキャッシュしているので、 (2) を以下のようにRuby上で計算するように変更する。
card_set.cards.select(&:remembered).size
するとクエリの発行が無くなりN+1を回避できる。
CardSet.where(user_id: user_id).preload(:cards)
SELECT "card_sets".* FROM "card_sets" WHERE "card_sets"."user_id" = $1 LIMIT $2 OFFSET $3 [["user_id", 1], ["LIMIT", 10], ["OFFSET", 0]] SELECT "cards".* FROM "cards" WHERE "cards"."card_set_id" IN ($1, $2, $3) [["card_set_id", 1], ["card_set_id", 2], ["card_set_id", 3]]
CardSet.where(user_id: user_id).eager_load(:cards)
SELECT DISTINCT "card_sets"."id" FROM "card_sets" LEFT OUTER JOIN "cards" ON "cards"."card_set_id" = "card_sets"."id" WHERE "card_sets"."user_id" = $1 LIMIT $2 OFFSET $3 [["user_id", 1], ["LIMIT", 10], ["OFFSET", 0]] SELECT "card_sets"."id" AS t0_r0, "card_sets"."public" AS t0_r1, "card_sets"."forked" AS t0_r2, "card_sets"."name" AS t0_r3, "card_sets"."user_id" AS t0_r4, "card_sets"."created_at" AS t0_r5, "card_sets"."updated_at" AS t0_r6, "cards"."id" AS t1_r0, "cards"."answer" AS t1_r1, "cards"."question" AS t1_r2, "cards"."hint" AS t1_r3, "cards"."remembered" AS t1_r4, "cards"."card_set_id" AS t1_r5, "cards"."created_at" AS t1_r6, "cards"."updated_at" AS t1_r7 FROM "card_sets" LEFT OUTER JOIN "cards" ON "cards"."card_set_id" = "card_sets"."id" WHERE "card_sets"."user_id" = $1 AND "card_sets"."id" IN ($2, $3, $4)
make testacc PKG=rds TESTS='TestAccRDSClusterInstance_basic'
結合試験は実際のAWS環境にリソースがデプロイされる。 デプロイされるリソースはこのへんで定義されてる
func testAccClusterInstanceConfig_base(rName, engine string) string { return acctest.ConfigCompose( acctest.ConfigAvailableAZsNoOptIn(), testAccClusterInstanceConfig_orderableEngineBase(engine, false), fmt.Sprintf(` resource "aws_rds_cluster" "test" { cluster_identifier = %[2]q availability_zones = [ data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1], data.aws_availability_zones.available.names[2] ] engine = data.aws_rds_engine_version.default.engine engine_version = data.aws_rds_engine_version.default.version database_name = "mydb" master_username = "foo" master_password = "mustbeeightcharacters" skip_final_snapshot = true } `, engine, rName)) }
main ブランチを持ってきているはずなのに。以下のエラーが出てハマった。。。
2024-02-20T18:18:39.014+0900 [ERROR] sdk.helper_resource: Unexpected error: error= | Error running apply: exit status 1 | | Error: creating RDS Cluster (tf-acc-test-xxxxxxxxx): DBSubnetGroupDoesNotCoverEnoughAZs: The DB subnet group doesn't meet Availability Zone (AZ) coverage requirement. Current AZ coverage: us-west-2c. Add subnets to cover at least 2 AZs. | \tstatus code: 400, request id: d4d1ccab-xxx-xxxx-xxxx-xxxxx | | with aws_rds_cluster.test, | on terraform_plugin_test.tf line 31, in resource "aws_rds_cluster" "test": | 31: resource "aws_rds_cluster" "test" {
どうやら前提として、 aws_rds_cluseter
の db_subnet_group
は省略すると以下の動作になるらしい(ドキュメントに明記しておいてほしい・・。多分無いと思う)
なので、既存のVPCにサブネット(AZ)を3つ作ったら解決した。 ちなみに、リージョンはデフォルトでオレゴン(us-west-2)が選ばれた。 これはテスト中に data ソースで Optin されているリージョンから先頭が自動で選ばれるみたい。これも分かりにくすぎるでしょ・・。
以下が分かりやすい。