Looping rules with ordinary rule sets?

Events happening in the community are now at Drupal community events on www.drupal.org.
itangalo's picture

Inspired by Rules 2 and some discussions regarding looping through lists and evaluating these lists as a whole I got some ideas of how to use rule sets to make a looping structure fit even the Rules 1 framework.

I guess the post is mainly aimed at the Rules maintainers (mostly fago and klausi), but I'm posting it here for public view. More eyes mean more ideas and – hopefully – better ideas.

Before I start I would like to say clearly that I know that loops are already implemented in Rules 2. I am not sure how this is made from a technical point of view (since I am basically a no-coder), but from what I've seen I think that I have a different approach. Consider this post an hypothetical idea that may or may not be worth taking any further.

The use case
It happens every now and then that you want to carry out actions based on multiple-value stuff. For example:

  • A node refers to several users, and messages should be sent to every user when the node gets updated.
  • A main node referes to several other nodes, and the referenced nodes should be unpublished if the main node is unpublished.
  • A comment has one or taxonomy terms attached to it, which are used for views lists of new comments. When a new comment is posted, the cache bin for the relevant views should be emptied.

Usually this is difficult, since Rules (and Token) assumes that you only want to deal with the first value in any multiple-value field. In most cases you could build a View that performs actions on multiple objects, but that means pretty large costs in terms of complexity, time to build the functionality and power it takes to execute it all. It would be much more neat if you could say 'do this action on all the stuff I have already gathered in this pretty array'.
Rules 2 allows this by adding loops as a nested kind of action inside a rule.

I would like to suggest a new way of calling rule sets, that iterate over a given array. This could be implemented as a separate module, much like Rules Scheduler uses rule sets in a particular way (and is isolated in a module of its own).

An approach like this would (I think) require the following:

  • A rules object Array that takes a multiple-value field. (For now I don't see how this can be generalized to work with other data.)
  • A rules action Loop through multiple-value fields calling any rule set. For every argument of type Array you must specify what other argument it should be mapped against. That is, if your array contains a multiple-value node reference field, you should have a content argument to assign its values to. If the array is user references or comments, you'd want to map it against user or comment arguments.
  • When called, the action Loop through multiple-value fields with rule set X calls the rule set once for every item in the array, with the proper arguments loaded.The rule sets behaves as usual, possibly with the exception that the array might provide tokens on the form [array:number] and [array:total] showing which item in the array you are currently at and the total number of items.
  • Possibly you allow multiple arrays, which means that the action Loop through multiple-value fields with rule set X evaluates the rule set once for each possible combination of arguments.
  • Possibly there is some extra conditions available, checking against [array:number] and [array:total].

Is this a decent approach? Is this crap compared to how Rules 2 implements loops?
(The reason for posting this is that I found it weird that loops were nested as special-type actions, but there may of course be reasons for this that I haven't thought about.)

Comments welcome.
//Johan Falk, NodeOne, Sweden

Comments

Sounds decent. While this

fago's picture

Sounds decent. While this doesn't make rules generally lists-aware, it would suffice for lots of use-cases I guess.

ad "Array": It should be list or "list" just as rules 2 uses.

(The reason for posting this is that I found it weird that loops were nested as special-type actions, but there may of course be reasons for this that I haven't thought about.)

What's wrong with that? I'd say that's more simple to use.

Return value in loop

a.milkovsky's picture

I use rules component in loop
Question. How can I return value from loop component?

(Drupal commerce)
I have two prices in my products. I want to use price 2 field if total of price2 in cart is bigger than 1000$.

I want to count the total price in my cart(Drupal commerce).
1. I create rule with condition Calculating the sell price of a product.
2. I create value to store total
3. I start my loop in cart for each line-item.
4. In loop for each line item I use rule component to get price2 of related product. I send line item and my value as parameters
5. In the component I Set a data value to price2 * quantity.
6. ??? I want to return calculated price of product to main rule and go to nwxt line item in loop

Rules

Group organizers

Group categories

Categories

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: