2015-05-29 101 views
2

我有以下的情况 -使用规则引擎

我有Company,我有Incident

A Company提供许多服务(Service),因此 - has_and_belongs_to_many :services

Incident需要一些服务(Service),因此 - has_and_belongs_to_many :services

现在对于一个给定的事件,我需要找到所有提供我所需要的服务公司。我期望使用规则引擎来做到这一点,因为我有更复杂的条件来适用于选择合适的公司。

我看着这个名为 - Wongi-engine(github.com/ulfurinn/wongi-engine)的宝石,但它太难缠我的头,写规则。

你能为我提供任何指针吗?谢谢!

我能想出以下facts

engine << [ "CompanyA", "offers", "serviceA" ] 
engine << [ "CompanyB", "offers", "serviceB" ] 
engine << [ "CompanyA", "offers", "serviceB" ] 
engine << [ "CompanyB", "offers", "serviceC" ] 
engine << [ "IncidentA", "requires", "serviceC" ] 
engine << [ "IncidentA", "requires", "serviceA" ] 

编辑: 也曾经我写这些规则,我怎么使用Rails的模型来代替这些字符串的?在Ruby on Rails应用程序的上下文中是否有将事实载入引擎的最佳实践?

我的用例是,用户选择一个事件并要求可以为事件提供服务的公司。我需要问规则引擎的公司名单,可以做的伎俩:)

回答

2

你可以做到与嵌套迭代引擎。

engine.each "IncidentA", "requires" :_ do |requires| 
    engine.each :_, "offers", requires.object do |offers| 
    puts "IncidentA can get #{requires.object} from #{offers.subject}" 
    end 
end 

要做到这一点作为一个原则...

suppliers = engine.rule "service suppliers" do 
    forall { 
     has :Company, "offers", :Service 
     has :Incident, "requires", :Service 
    } 
end 

然后使用规则,选择事件的类型和重复的信息。

suppliers.tokens.select{|s| s[:Incident] == "IncidentA" }.each do |s| 
    puts "#{s[:Incident} can get #{s[:Service]} from #{s[:Company]}" 
end 

要做到这一点作为一个查询...

q = engine.query "companies" do 
    search_on :Incident 
    forall { 
     has :Company, "offers", :Service 
     has :Incident, "requires", :Service 
    } 
end 

engine.execute "companies", { Incident: "IncidentA" } 
q.tokens.each do |s| 
    puts "#{s[:Incident} can get #{s[:Service]} from #{s[:Company]}" 
end 

编辑增加了对你的问题的笔记有关填充facts ...

假设你有Company与属性nameIncident与具有属性nameService的属性name

Company.joins(:services).select("companies.*, services.name as service_name").each do |company| 
    engine << [company.name, "offers", company.service_name] 
end 

Incident.joins(:services).select("incidents.*, services.name as service_name").each do |incident| 
    engine << [incident.name, "requires", incident.service_name] 
end 
+0

太棒了。谢谢你。所有这些使得现在更加合理。我会尽力将其纳入我的应用程序。 –

+0

还有一件事,我该如何将我的Rails应用程序与我的服务,事件和公司模型进行整合?有没有什么好的做法将事实加载到引擎中?谢谢!!编辑此部分的问题:) –

+0

好的,我修改了这个问题,以显示如何使用一些ActiveModel内部连接填充事实。 – SteveTurczyn