On rules versus hooks, or, abstraction shock

I need to add a bit of business logic to my Commerce site: a boolean field on product nodes marks that the corresponding products can't be delivered outside the UK.

And I know the way to do this in Commerce is to create a rule: react to the cart completing checkout, iterate over line items, check the corresponding products, and block the completion if the field in question is set.

Rules is great: with Rules, site builders can change site functionality and cause it to react to events. When non-techy people ask if my job involves designing websites, to put them right I say, 'I make websites go "bing!"'; and now, site builders can make them go 'bing!' too.

But I have a confession: I'm reluctant about using Rules. It's partly that I find the UI confusing, and it feels time-consuming to test them, but deeper than that I think it's just that I feel too far removed from the actual thing I'm trying to make.

And that makes me wonder: am I becoming a Drupal dinosaur?

Because I can imagine when Views first came along, developers who were used to writing their own query and formatting the result themselves, looking at the Views UI and thinking 'I don't feel in control of my lists of stuff any more'.

Or before CCK, developers wrote exactly the form elements they needed in the node form and saved it themselves in the database. I still sometimes speak to non-Drupal developers who want to be able to dump data into the node table directly (or pull it out) and when I tell them they can't, because the data that actually makes a node is spread out over the node table, the node_revision table, and then a multitude of field tables. And their feeling of disconnection at not being able to get their hands on 'the node' as a solid lump of database stuff must surely be akin to what I feel with Rules. And I'm going to call this feeling 'abstraction shock'.

I want to write a hook. I want to write the code for it, for it to feel like a solid thing. I know that my rule can (indeed, should) be exported to code, but I want code that I can read and see exactly what it says, rather than code that Rules will consume and understand. And most of all, I want to be able to put in debug statements to understand what I'm getting as I write it, and after I've written it when it's going wrong or when the site functionality has to change.

If that makes me a dinosaur, save me a seat next to the brontosaurus.

10 comments

by Jon Pugh on Fri, 21/09/2012 - 23:19

Thank you for bringing this up!

Rules drives me crazy for the same reason... especially in cases like this, where the logic of the business is depends on it working!

I always say, if you need business logic, do NOT use rules!

by Ariel Gold on Sat, 22/09/2012 - 00:39

One thing that might make you feel more in control is to export the rule. Then you have it in code, can modify it there, and commit it to version control.

More here:
http://jamestombs.co.uk/2012-09-19/drupal-7-defining-rules-within-module...

by yakoub abaya on Sat, 22/09/2012 - 08:26

you are not supposed to use rules for complex logic , period .
and nay person who thinks rules be developed to reach a state where people uses it for complex structures logic , then that person is living an illusion and chasing mirage

same as views can't be used to calculate complex statistics and make heavy batch jobs without implementing a view handler class

also same as fields (cck) can't be used to implement complex structures efficiently, be cause if you have a scientific or economic "data" entity and not a "node" then you don't want to have 100 tables for 100 float values instead of just one table with 100 columns

it is all the same logic, with all the drupal contrib all it can do is provide site designers some tools to get simple tasks done, and that is great because a 90% of sites out there are all simple tasks that doesn't require hiring a developer to implement them and that is where drupal contrib should concentrate and not waste time on chasing the mirage of using conrtib to implement the 10% of site that will require a team of developers sooner or latter

by thedavidmeister on Sat, 22/09/2012 - 10:11

FWIW I don't think you're a dinosaur :) we've just spent a fair bit of our last development cycle pulling Rules *out* of a reasonably large project we were working on. I'll give a disclaimer in that this was D6 not D7 and things may well be different there but here's the most salient points from our internal discussions:

1. Rules has to pull its definitions out of the cache as it works, our current setup is being limited by CPU and unserialize() was coming up pretty high on the profiler for some pages, so anything we could avoid having to unserialize objects is a bonus to us. There's also another performance hit in running any Rule that runs php code through eval(); extending Rules through hooks to avoid eval() is simple enough, but why would you write hooks just to avoid writing hooks?

2. It's not immediately obvious but we've found that the exportability of Rules is not nearly as good as Views or the other "big" modules. Because of the data structure of rules, the data of all your exported rules is "interleaved" with each other and dumped into the generic "features.inc" file (and the order *seems* to be different for me every time I do an export so I just get an infuriating mess of random additions and subtractions in git) rather than sequentially one after another in it's own, dedicated .inc file so reviewing your changes in git is much harder than it has to be. Additionally, contrib modules all seem to have defined their own way of exporting rules slightly differently; it looks like the API must have "evolved" over time and there's some backwards compatibility stuff that means exported rules don't even always have the same syntax - I've had Features with rules in them complain about being "overwritten" even after running "DELETE FROM {rules_rules}" in an update hook. Admittedly this is usually "cosmetic" stuff as the Rules (usually) export just fine and the UI lies about the Features being in the default state but I have had some "human error" issues with multiple developers stepping on each other's toes during merges because of these issues that basically led to us deleting all of our rules manually from a Feature and re-exporting them. I've also had Rules exported through the Features UI that led to fatal errors on the Rules admin page due to it not handling PHP data types correctly. (yes, I've been trying to help out on issues in the issue queue and submitted a few patches, but the problems seem pretty deeply ingrained in the module's structure and the way it handles data :/)

3. Out of the box Rules does not really provide extra functionality over what hooks provide. There are some 3rd party modules that let you do cool things with VBO and scheduling rules to fire periodically, for example, but if you don't need these features then Rules boils down to a 1:1 UI for the hooks system with some fairly trivial boilerplate things you can do like "send email" or "unpublish node".

4. Because the exportability is kind of scrappy and writing a Rule definition by hand is difficult you need to use the UI to do anything with Rules, and you're not "supposed" to leave the UI module active on your production site. This means that cleanly pushing a fix for a buggy rule in a production site between releases is often much harder than applying a patch for a single hook.

5. I don't think it's entirely fair to compare the difference between Rules and hooks to working directly with the database to nodes, or working with forms to cck - Those two things are encouraging site builders to work in a way that is interoperable with all 3rd party modules on d.o. (using nodes instead of the db invokes the Drupal node api, using cck allows nodes to be extended in a standardised way) and the things they abstract are really complicated and easy for new developers to screw up! Swapping out a few hooks with Rules that implement trivial behaviour like "unpublish node when X happens" just doesn't have that same impact on the long-term maintainability of a Drupal site..

As with moving to any new system you have to ask yourself what benefit you actually get from the change, because migrations are expensive. Using Drupal's core hook system has real advantages over using Rules, but for many people the Rules UI will always be a "friendlier" alternative to working directly with the hooks system and for that reason alone it will probably remain popular for a very long time.

tl:dr; We found that over the long term the Rules module was slowing our developers down more than helping them out by over-abstracting relatively straightforward behaviour while not really simplifying anything that we were finding too complicated to do ourselves in a reasonable time-frame.

by Ryan on Sat, 22/09/2012 - 17:26

Our philosophy behind Rules in Drupal Commerce is to use it to avoid hard coding business logic directly into the core modules themselves. It's simply easier for most people to disable an unwanted rule than it will be to unregister a core hook implementation - the clearest example being the rules that create user accounts for anonymous customers post-checkout.

However, for every event except one, we're invoking the event with rules_invoke_all(), which first invokes the Rules event and then performs module_invoke_all() with the exact same hook name and parameters. For business logic on a site that simply won't need to be reconfigured or that is complex enough to make coding it in the Rules UI a pain, I'd happily recommend using the hook instead of Rules.

by mradcliffe on Sat, 22/09/2012 - 18:04

I think not leveraging views or fields would make you a dinosaur. When I started using views it felt like a weight lifted off of my back. With rules I don't see it a a replacement because it will never be ate placement for complex logic. Event-condition-action, even with rule sets doesn't come close to real code. I can't count the number of times I thought I could do something with rules and then realized that I needed just a bit more. At the samtime rules has helped lift the load and provided a more maintainable site.

by Kevin on Sun, 23/09/2012 - 15:39

I know what you mean.

Field/Views are great modules, but when I am working on complex sets of data, I try to use Entity properties as much as possible, especially if it is just a single piece of data. The overhead of Fields I find is just too much. I pretty much only use it for file/images or things of that nature.

That way, I can leverage EFQ as much as possible, and not use Views, and get practically the same result and the app performance speed will increase. Plus, I can see everything that is going on in the code.

by dalin on Mon, 24/09/2012 - 18:26

I don't think this makes you a dinosaur. The reasons that you give are perfectly valid for the style of development that you (and I) are doing. And just like Views vs. queries there are some styles of development where queries are the better choice. However I see hooks being the better choice (as opposed to Rules), more often than queries is the better choice (as opposed to Views).

by dwkitchen on Thu, 27/09/2012 - 14:24

First off I have to agree with thedavidmeister, the Rules UI can be a pain and exporting them from the UI of with Features might be quick but it is not a developer friendly method.

However in my work on the Commerce EU VAT module I was forced to use rules as Commerce uses it for calculating taxes. At first I got frustrated with not being able to get rule options to depend on if a module is enabled.

I knew there must be a better way and looked at how rules_import() (Shown in the http://jamestombs.co.uk/2012-09-19/drupal-7-defining-rules-within-module... James Tombs blog post) works, and tried to learn how to write a rule in code -- for which there is almost no documentation.

The http://drupalcode.org/project/commerce_eu_vat.git/blob/refs/heads/7.x-1.... is a great starter example.

hook_default_rules_configuration() registers four rules, one of which is only registered if Commerce Shipping is enabled. hook_default_rules_configuration_alter() then starts to change default rules created by the Commerce Tax module.

I now find that I might have a go at trailing a rule in the UI but I will actually write the rule in code and keep it in version control.

by Chris Calip on Wed, 03/10/2012 - 18:47

I have ambivalent feeling about rules vs hooks i also think its a judgement call depending on the situation.
On a different but related note what do you guys of the possible unsaid standard of contrib module development of exposing apis through hook AND rules now; instead of just hooks.

Post new comment

Filtered HTML

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
  • To post pieces of code, surround them with <code>...</code> tags. For PHP code, you can use <?php ... ?>, which will also colour it based on syntax.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.
© 2010 Greg Harvey. Drupal theme by Kiwi Themes.