[編輯2]
鑑於articles_per_week不是一個領域,但一個方法,你必須放棄範圍chainability - 歸結範圍只是AREL產生一個SQL語句,沒有辦法彌合實例方法和數據庫之間的差距。在這一點上,其實事情變得更加容易,你可以直接使整個事情一類的方法,並在最後以呼叫#reject砸不符合計數標準的:
class Batch < ActiveRecord::Base
belongs_to :project
has_many :articles
def self.all_completed
joins(:articles).
includes(:project).
where("articles.status = 'Completed'").
group("batches.id").
select("batches.*, count(articles.id) as article_count").
reject {|batch| batch.article_count.to_i < batch.project.articles_per_week}
end
end
而且,你仍然可以通過這個(2)獲得最小的DB命中。但是,如前所述,調用#reject會將您的輸出轉換爲基本的對象數組,而不是可鏈接的ActiveRecord集合。
不知道爲什麼我不得不將物品數量轉換爲整數,但事實確實如此。
我已經離開了我的以前的版本,因爲我認爲他們提供了其他情況的好的附加信息。
[編輯1]
這裏是你可以把上批一個範圍的版本,所以它的可鏈接到其他領域。
scope :all_completed,
joins(:articles, :project).
where("articles.status = 'Completed'").
having("count(articles.id) >= projects.articles_per_week").
group("batches.id").
select("batches.*, projects.articles_per_week")
我在測試這一點,它可以對一些標準的ActiveRecord的方法產生影響注意。例如,#size不起作用,因爲在ActiveRecord上被轉換爲SELECT COUNT(*),並且由於所選字段中缺少projects.articles_per_week,在這裏不起作用。
[原創]
我在這裏的第一個答案。
我不確定這是否符合您的「簡單」請求,但它在一個SQL語句中完成任務。
Article.includes([:batch => :project]).where(:status => 'Completed').group(:batch_id).having("count(articles.id) >= projects.articles_per_week").map(&:batch)
這是假設的Rails 3和下面的模型設置:
class Batch < ActiveRecord::Base
has_many :articles
belongs_to :project
end
class Project < ActiveRecord::Base
has_many :batches
end
class Article < ActiveRecord::Base
belongs_to :batch
end
順便說一句,這是我的測試數據。在結構上正確地拉批次1和2,而忽視一批3.
-- phpMyAdmin SQL Dump
-- version 3.3.2deb1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jun 27, 2011 at 07:13 PM
-- Server version: 5.1.41
-- PHP Version: 5.3.2-1ubuntu4.9
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
--
-- Database: `stack_development`
--
-- --------------------------------------------------------
--
-- Table structure for table `articles`
--
DROP TABLE IF EXISTS `articles`;
CREATE TABLE IF NOT EXISTS `articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`batch_id` int(11) DEFAULT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`status` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=16 ;
--
-- Dumping data for table `articles`
--
INSERT INTO `articles` (`id`, `batch_id`, `name`, `status`, `created_at`, `updated_at`) VALUES
(1, 1, 'Test 1 Article', 'Completed', '2011-06-27 22:38:55', '2011-06-27 22:38:55'),
(2, 1, 'Test 2 Article', 'Completed', '2011-06-27 22:40:36', '2011-06-27 22:40:36'),
(3, 1, 'Test 3 Article', 'Completed', '2011-06-27 22:40:42', '2011-06-27 22:40:42'),
(4, 1, 'Test Article 4', 'Completed', '2011-06-27 22:38:55', '2011-06-27 22:38:55'),
(5, 1, 'Test Article 5', 'Pending', '2011-06-27 22:38:55', '2011-06-27 22:38:55'),
(6, 2, 'Test 1 Article', 'Completed', '2011-06-27 22:38:55', '2011-06-27 22:38:55'),
(7, 2, 'Test 2 Article', 'Completed', '2011-06-27 22:40:36', '2011-06-27 22:40:36'),
(8, 2, 'Test 3 Article', 'Completed', '2011-06-27 22:40:42', '2011-06-27 22:40:42'),
(9, 2, 'Test Article 4', 'Pending', '2011-06-27 22:38:55', '2011-06-27 22:38:55'),
(10, 2, 'Test Article 5', 'Pending', '2011-06-27 22:38:55', '2011-06-27 22:38:55'),
(11, 3, 'Test 1 Article', 'Completed', '2011-06-27 22:38:55', '2011-06-27 22:38:55'),
(12, 3, 'Test 2 Article', 'Completed', '2011-06-27 22:40:36', '2011-06-27 22:40:36'),
(13, 3, 'Test 3 Article', 'Pending', '2011-06-27 22:40:42', '2011-06-27 22:40:42'),
(14, 3, 'Test Article 4', 'Pending', '2011-06-27 22:38:55', '2011-06-27 22:38:55'),
(15, 3, 'Test Article 5', 'Pending', '2011-06-27 22:38:55', '2011-06-27 22:38:55');
-- --------------------------------------------------------
--
-- Table structure for table `batches`
--
DROP TABLE IF EXISTS `batches`;
CREATE TABLE IF NOT EXISTS `batches` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`project_id` int(11) DEFAULT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=4 ;
--
-- Dumping data for table `batches`
--
INSERT INTO `batches` (`id`, `project_id`, `name`, `created_at`, `updated_at`) VALUES
(1, 1, 'Test 1 Batch', '2011-06-27 22:38:11', '2011-06-27 22:38:11'),
(2, 2, 'Test 2 Batch', '2011-06-27 22:38:11', '2011-06-27 22:38:11'),
(3, 3, 'Test 3 Batch', '2011-06-27 22:38:11', '2011-06-27 22:38:11');
-- --------------------------------------------------------
--
-- Table structure for table `projects`
--
DROP TABLE IF EXISTS `projects`;
CREATE TABLE IF NOT EXISTS `projects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`articles_per_week` int(11) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=4 ;
--
-- Dumping data for table `projects`
--
INSERT INTO `projects` (`id`, `name`, `articles_per_week`, `created_at`, `updated_at`) VALUES
(1, 'Test 1 project', 3, '2011-06-27 22:37:11', '2011-06-27 22:37:11'),
(2, 'Test 2 Project', 3, '2011-06-27 22:37:21', '2011-06-27 22:37:21'),
(3, 'Test 3 Project', 3, '2011-06-27 22:37:21', '2011-06-27 22:37:21');
對不起,我並不清楚 - 你想要什麼從批號爲#返回all_completed? – Yardboy
我希望它返回批處理的所有實例,滿足方法中的條件 –