How am I meant to structure my dry-web-roda app's operations and repos?

I’m trying the new dependency injection Ruby stuff. I’ve made a new app from the template. I’m trying to have this app display a contact form and record responses for later action. This should be trivial enough, right?

My understanding based on trying to read through the documentation scattered across nine different sub-gems, Slideshare posts titled “meet rom-rb”, old blog posts announcing dry-system, the Icelab blog post “Effective Ruby dependency injection at scale” and the Berg application source. These disparate documents are really hard to integrate into one idea of how things work, but I haven’t found a single document that tells me what I need to know.

What I think I know tells me I should go something like:

  • generate the app using dry-web-roda because otherwise you will be in dependency-manager-setup-hell forever
  • throw together a few migrations
    • there’s a rake task to make the migration file
    • the API docs for this live under the gem ‘Sequel’
  • make apps/main/web/routes/contact with a get and a post
  • make apps/main/lib/main/views/contact/show.rb to show the form
    • all it has is config.template = "contact/show" because you’re just copying from views/welcome.rb
    • make apps/main/web/templates/contact/show.html.slim to go with it
      • the thing you need to make the form work is a line == csrf_tag (which is defined in some view context class. do not use a bare csrf_tag, that’ll be interpreted like a <csrf_tag/>. welcome to Slim.)
  • make apps/main/lib/main/views/contact/thanks.rb to show the “thank you” message after the form. (not very RESTful but hey it’s not really meant to be today.)
  • make Project::Operations::Contact to do the work of handling the form
    • it inherits from Project::Operation which was autogenerated
    • it lives at lib/project/operations/contact.rb I guess??!? i have no validation this works
    • first draft version will access a repo directly to persist an operation to the database
      • not 100% sure where to put this yet but expect it’ll be lib/project/repo/blahblah inheriting from Project::Repository[:blahblah] – much like ROM docs on repositories – and I’ll inject it with Project::Import['repo.blahblah']
  • Access the operation in the route
    • to access it do… what??? self.class["operations.contact"]??!? that’s totally not working
    • later, use operation.call to invoke it
  • (later, in the distant future, clean it all up, use the initial contact to initiate a crazy CRMy workflow that will actually benefit from properly structured concerns.)

So, while self.class["operations.contact"] seems to be the way to get at things that are registered, there is nothing registered with the key "operations.contact" and all I get is errors which I have no idea how to debug, because I can’t find documentation or a working example anywhere. (Also, I’ve no idea if the repo works.)

How am I meant to structure my app with these concerns?
How do I debug the case where something is not loading?

Hi @twhaples.

We know that their missing Documentation for everything is an endless task. I know at first it could look quite complicated I’ve been there.

From your comment I think you have the latest version of dry-web-roda that includes Operations, I have a blog post
I have to say that the structure is not the same since I use a lower version in the example.

In your comment that using Import I have to say without seeing the code, usually you have to set your auto_register to access those files we follow a simple convention based on the file structure to resolve the name to access them.

If you have more doubts you can share it here I will try my best to help you if you share the repo I can check the code understand it better.

Thanks for sharing.

Hi Gustavo. You’ve just proposed that I auto_register a bunch of files, but the whole point of the dry-web-roda auto-generated template was to set up things like auto-registration for me so that I don’t have to spend days code-reading and experimenting to understand which paths are relative to which, where the appropriate place for auto-registration setup is so that it works seamlessly in tests and web applications, and the like. Otherwise, I’d just be using dry and roda independently.

Since I asked my question, I have conducted additional experiments and determined that I am correct, and that if I store the operation in question in lib/main/operations/contact.rb (specifically using the name main, which is the name of the autogenerated application under apps/, as opposed to the name of the project containing it) then things work automatically as expected.

I no longer need to know the answer to this specific question and am placing the answer here for people who are trying to figure out how to actually use the dry-web-roda template.

Hi @twhaple.

First of all sorry I haven’t been able to answer your question in the first place.

Yes by default if you set up an umbrella project, under the apps folder you will find your main app maybe in the future we add support to specify the name of the folder of the main app.

The container for main app has setup by default the auto_regitration of the lib/main folder. So everything that you put under that folder can be accessed following the convention that dry-system has for auto-import.

Having an umbrella setup allows you to have everything well organized for each app of your application, each application with its own Import, etc…

Hope this helps.