throughを使って孫の数を数える
検証用にモデルを作成
bundle exec rails g model a bundle exec rails g model b a:references bundle exec rails g model c b:references bundle exec rake db:migrate
モデルに関連を追加
class A < ActiveRecord::Base has_many :b has_many :c, through: :b end class B < ActiveRecord::Base belongs_to :a has_many :c end class C < ActiveRecord::Base belongs_to :b end
pry
[19] pry(main)> a = A.new => #<A id: nil, created_at: nil, updated_at: nil> [20] pry(main)> a.save (0.1ms) BEGIN SQL (0.2ms) INSERT INTO `as` (`created_at`, `updated_at`) VALUES ('2015-03-19 18:43:31', '2015-03-19 18:43:31') (0.8ms) COMMIT => true [21] pry(main)> b = a.b.build => #<B id: nil, a_id: 3, created_at: nil, updated_at: nil> [22] pry(main)> b.save (0.1ms) BEGIN SQL (0.2ms) INSERT INTO `bs` (`a_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:40', '2015-03-19 18:43:40') (0.8ms) COMMIT => true [23] pry(main)> 15.times { b.c.build.save } (0.1ms) BEGIN SQL (0.2ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (1.3ms) COMMIT (0.2ms) BEGIN SQL (0.2ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT (0.1ms) BEGIN SQL (0.1ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT (0.1ms) BEGIN SQL (0.2ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT (0.1ms) BEGIN SQL (0.2ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT (0.1ms) BEGIN SQL (0.2ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT (0.1ms) BEGIN SQL (0.2ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.2ms) COMMIT (0.1ms) BEGIN SQL (0.1ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.2ms) COMMIT (0.1ms) BEGIN SQL (0.1ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.6ms) COMMIT (0.1ms) BEGIN SQL (0.1ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT (0.1ms) BEGIN SQL (0.1ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT (0.1ms) BEGIN SQL (0.2ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT (0.1ms) BEGIN SQL (0.2ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT (0.1ms) BEGIN SQL (0.2ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT (0.1ms) BEGIN SQL (0.1ms) INSERT INTO `cs` (`b_id`, `created_at`, `updated_at`) VALUES (3, '2015-03-19 18:43:46', '2015-03-19 18:43:46') (0.3ms) COMMIT => 15 [24] pry(main)> a.c.count (0.3ms) SELECT COUNT(*) FROM `cs` INNER JOIN `bs` ON `cs`.`b_id` = `bs`.`id` WHERE `bs`.`a_id` = 3 => 15 [25] pry(main)>