开发者

Referencing associations with Ruleby on Rails

I've recently started messing with a gem called 'ruleby', a rule-engine for Ruby. The documentation for ruleby is a bit sparse, however, and I can't seem to figure out how to properly reference associations for the rule-writing bit. I'm stumped both the 'pattern' part of the rule and also in the executing block part of the rule.

For example, let's say I had a rule which would only be executed only when a user submitted a positive review. I could, for instance, write the following:

    rule :positive_review, [Review, :review, method.review_rating == "positive"] do |v|
        assert (store positive_review somehow)
    end

So it's at this point that I get lost. I would like to write a rule which would reference back to the user and check the total number of positiv开发者_StackOverflow社区e reviews that the user of this positive review and possibly execute certain actions based on this number.

If anyone could point me in the right direction, I would be greatly appreciative. Thanks.


I dont quite understand why you are asserting a fact inside of a rule, that should already be done. The github example code probably answered you by now but in case not:

First you initialise the engine, I did it like this so I could call on it more than once.

rule_engine = Ruleby::Core::Engine.new
RULES_ENG = RulesEngineCaller.new(rule_engine)
EngineRulebook.new(rule_engine).rules

Then you assert your facts

@events = Event.all
@events.each do |event|
    @rule_engine.assert event
end

Then you run your engine

@rule_engine.match

if you want to add events you can just by calling assert per fact to the existing engine, it will just add to it until you either delete inside the engine or rebuild it.

The rulebook is where you add your facts for me I did it programatically:

class EngineRulebook < Rulebook
  def rules
    Rails.logger.debug "#{Time.now.utc} - Loading Rules into Rulebook"
    #msg = Notification.new()
    @rules = Rule.all

    @rules.each do |rule_name|
    case
     #hard coded rule - for auto cleaning
     when (rule_name.title == "SYSTEM ADMIN - auto-clean delete rule") && (rule_name.group.title == "Notification Admin")
      rule [Event, :m, m.terminate_flag == 1] do |v|
        if v[:m].rules.include?(rule_name) == false
          #output matched rule to console & logfile
          Rails.logger.info "#{Time.now.utc} - match rule #{rule_name.id} #{rule_name.title} - #{v[:m].ticket_id} - #{v[:m].description}"

          #add reference so rule doesn't fire again
          @event = Event.find_by_id(v[:m].id)
          @event.rules << rule_name
          v[:m].rules << rule_name
          modify v[:m]
          #Retract v[:m] would remove the fact from the rules engine, need to remove all related facts though
          #so dont use this as other rules may be requires as rules do not fire in order
        end
      end
   end

I also did it as a case statement as I was loading rules programmatically. I also put a check in to say has this rule run before because each time you run the engine it will assess all facts, even ones that have already matched.

Hopefully you have an answer, if not hopefully this helped.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜