Использование системы правил

У меня такая ситуация -

У меня Company и у меня Incident.

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?

Мой вариант использования: пользователь выбирает инцидент и спрашивает компании, которые могут его обслужить. И мне нужно спросить у движка правил список компаний, которые могут помочь :)


person Steve Robinson    schedule 29.05.2015    source источник


Ответы (1)


Вы можете сделать это с помощью вложенных итераций в движок.

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

ИЗМЕНИТЬ добавление примечаний к вашему вопросу о заполнении _5 _...

Предположим, у вас есть Company с атрибутом name и Incident с атрибутом name и Service с атрибутом 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
person SteveTurczyn    schedule 29.05.2015
comment
Потрясающий. Спасибо за это. Все это теперь имеет гораздо больше смысла. Я постараюсь включить это в свое приложение. - person Steve Robinson; 30.05.2015
comment
Еще одна вещь, как мне интегрировать это с моим приложением rails, где у меня будут модели услуг, инцидентов и компаний? И есть ли какие-нибудь хорошие практики для загрузки фактов в движок? Спасибо!! Отредактировал вопрос с этой частью :) - person Steve Robinson; 30.05.2015
comment
Хорошо, я изменил вопрос, чтобы показать, как можно заполнить факты с помощью некоторых внутренних соединений ActiveModel. - person SteveTurczyn; 31.05.2015
comment
Спасибо! :) Стив, еще кое-что. Является ли хорошей практикой хранить эти факты в базе данных или загружать их, когда нам нужно запрашивать или хранить их в кэше в Redis или в чем-то еще? Ваши предложения? Принял ваш ответ кстати. - person Steve Robinson; 01.06.2015