有四种模式:汽车,人,国家和宗教。
class Car < ActiveRecord::Base
belongs_to :person
has_one :country, through: :person
has_one :religion, through: :person
def self.get_indian_cars_owned_by_hindus
self.joins(:country).joins(:religion).where("countries.name=? and religions.name=?", 'India', 'Hindu').count
end
end
class Person < ActiveRecord::Base
belongs_to :country
belongs_to :religion
has_one :car
end
class Country < ActiveRecord::Base
has_many :persons
end
class Religion < ActiveRecord::Base
has_many :persons
end
模型中的函数get_indian_cars_owned_by_hindus可以在表格中使用某些条件。宗教。调用函数时生成的查询是:
SELECT COUNT(*) FROM `cars` INNER JOIN `persons` ON `persons`.`id` = `cars`.`person_id` INNER JOIN `countries` ON `countries`.`id` = `persons`.`country_id` INNER JOIN `persons` `persons_cars_join` ON `persons_cars_join`.`id` = `cars`.`person_id` INNER JOIN `religions` ON `religions`.`id` = `persons_cars_join`.`religion_id` WHERE (`countries`.`name` = 'India') AND (`religions`.`name` = 'Hindu');
我最初期望查询是这样的:
SELECT COUNT(*) FROM `cars` INNER JOIN `persons` ON `persons`.`id` = `cars`.`person_id` INNER JOIN `countries` ON `countries`.`id` = `persons`.`country_id` INNER JOIN `religions` ON `religions`.`id` = `persons`.`religion_id` WHERE (`countries`.`name` = 'India') AND (`religions`.`name` = 'Hindu');
这里的ActiveRecords没有优化人员和汽车表之间的额外连接。虽然我相信mysql会在最后优化它,但是在the rails way
中正确编写它的方式是什么。
我显然可以在模型人员中移动方法,但这不是我正在寻找的解决方案。可能存在多个节点的情况。
编辑:将A,B,C和D的模型名称分类为汽车,人员,国家和宗教
答案 0 :(得分:1)
最好的选择是将join
调用更改为不使用has_many :through
关系。相反,您可以将深层关系嵌套在数组中,如下所示:
def self.get_indian_cars_owned_by_hindus
self.joins(:person => [:country, :religion]).
where("countries.name=? and religions.name=?", 'India', 'Hindu').
count
end