我正在开发一个系统,用户输入几个症状并收到与这些症状相匹配的所有疾病的列表。 然而,我还没有找到办法。
例如,如果用户有"发烧"和#34;打喷嚏"作为症状,我希望系统能够同时找到同时发烧和打喷嚏的所有疾病并按顺序列出。
我有三个表:illnesses
,symptoms
和illness_symptoms
。疾病和症状通过has_many
都有illness_symptoms
关系。
疾病和症状都被类似地映射:文本,描述和id字段。 illness_symptoms
只有id_symptom
和id_illness
。症状得到了保存"通过指定一种疾病和一种症状的形式来治疗疾病,虽然这是初步的,将在以后更改。
使用@illness = symptom.illnesses
我可以找到并列出具有某种症状的所有疾病,但我不确定如何缩小它的一秒(和任何后续)症状。
答案 0 :(得分:2)
您可以使用聚合函数
symptoms = Symptom.find(1,2)
illnesses = Illness.joins(:illness_symptoms)
.where("illness_symptoms.symptom_id in (?)", symptoms)
.group("illnesses.id")
.having("count(illnesses.id) >= ?", symptoms.length)
要回答您的评论 - 最好在模型中查询数据库。我会在疾病模型中制作一个范围:
scope :with_symptoms, -> (symptoms) { joins(:illness_symptoms)
.where("illness_symptoms.symptom_id in (?)", symptoms)
.group("illnesses.id")
.having("count(illnesses.id) >= ?", symptoms.length) }
并在需要的地方使用它。例如。 Illness.with_symptoms(Symptom.find(1,2))
答案 1 :(得分:0)
你可以做一个交叉 - 获取一个的id并限制另一个的结果以获得最终的交集。一定要在symptom_id和illness_id上索引sick_symptoms。
您可以编写一些内容来扩展它以获取数组并隐藏详细信息,但这是一个示例。
# for example
fever = Symptom.find(1)
sneezing = Symptom.find(2)
@illnesses = Illness.with_symptom(fever).where(:id => Illness.with_symptom(sneezing).pluck(:id))
将范围添加到疾病类
class Illness < ActiveRecord::Base
has_many :illness_symptoms
has_many :symptoms, :through => :illness_symptoms
scope :with_symptom, -> (symptom) { joins(:illness_symptoms).where(:symptom_id => symptom) }
end
答案 2 :(得分:0)
要通过症状查找疾病,您可以在sql中使用cities
用户输入多个症状的文本数组。你可以这样做:
IN
我希望这对你有所帮助。