Import slice components into main app

How do I use a component from a slice in my main application?

I’ve created a slice to contain the business logic for a domain in my application. Now, I would like to be able to use one of the components in that slice in my main application, but I cannot seem to figure out how to access it.

I am relatively new to Hanami, so I could be thinking/approaching this incorrectly.

I know it’s not what your’e asking, but I’d not use the main application in the first place, but rather have a separate slice for business, and separate slice for the main application.

Could you share what you have tried so far? I expect that this didn’t work?

import from: :business

Ref: V2.1: Slices | Hanami Guides

Thanks for your reply.

So, do you think the /app directory serves any purpose? I checked out your example app a little. Looks like you have some base types defined there.

I skimmed through this thread on app structure. I probably need to give it another read.

Yeah, I tried import. It doesn’t work as described for slices because slice.parent is nil. :frowning:

Hi, @aaricpittman.

The bottom line is that app and any slices you create simply act as “containers” in Hanami’s component management system. This really just means that they are namespaces that get auto-loaded when your app boots.

This section of the Hanami guides walks through the boot process and how components in the app directory get auto-loaded.

This section discusses “containers” and the component management system in more depth. Pay attention to the section on dependency injection. Even though all of the examples use components from the app container, you will use the same technique to access components you create in your slices.

Finally, the slices guide should pull it all together for you, particularly the section on slice imports and exports.

Here is some troubleshooting advice using the Hanami Console. In your project directory, run bundle exec hanami console. In the console, run Hanami.app.boot and then Hanami.app.keys. This will show you all of the available components in the app directory. In a new app, it will look something like this:

test[development]> Hanami.app.keys
["settings",
 "notifications",
 "hello_world",
 "routes",
 "inflector",
 "logger",
 "rack.monitor"]

These are the default components. Others that you create will show up here. If you wanted to use any of these components from within a slice that you create, you could use the include Deps “mixin.” I think it would look like this:

# From within a slice:

include Deps["app.settings"]

When you create a slice, it gets its own container. You can interact with the container in the console, just as we did with app above. For example, if you have an Admin slice with an index action, you can view your registered components like this.

test[development]>> Admin::Slice.boot
=> Admin::Slice
test[development]> Admin::Slice.keys
=> ["actions.index",
 "inflector",
 "logger",
 "notifications",
 "rack.monitor",
 "routes",
 "settings"]

You could then access Admin slice components from another slice or from app like this:

include Deps["admin.actions.index"]

I’m typing most of this from memory, so I hope I haven’t gotten anything wrong here. In any event, the guides I referenced do cover this stuff and should be adaptable to your situation.

As for when and how to use slices, that is a philosophical question at heart. The thread you referenced is more of a debate over how Hanami apps might be organized. Not all of this is settled yet (at least publicly), so that thread might just be more confusing than helpful in relation to your question.

If you are coming from Rails, you might choose to keep everything in app, and that’s just fine. If you need more robust organization, you might choose to use slices and organize them as you see fit. That kind of experimentation and exploration will help guide the direction that Hanami takes in the future.

Good luck! I’m excited about Hanami 2 and I’m glad to see others that are too. :slight_smile:

1 Like

I intentionally was careful in showing business logic extraction in my tutorials, and with working with multiple slices so far. That will change soon, but I did not wat to impact how people organize stuff too early as it’s not yet clear to me what’s the best approach.

ATM Personally I treat app as the code which contains very common code for the application. @timriley stores there relations which makes some sense to me because this is refecting database structure you have.

In my head the code from app is meant to be used in most slices. You could achieve this by having sth like shared slice, or commonto but the app folder is already there.

Having that said I do threat slices like the UI entry points at the moment, and I would store my business logic in lib or the app folder

I plan to explore different ideas though and have no clea answer for you.

Here are some thoughts I follow atm

  1. Start apps with the main slice first
  2. Common code, like types store in the widely accessible app folder
  3. Use interactors as an entry point to business , but keep in the main slice or the app for simplicity. It also allows me to use the Deps module for quick and easy dependency injection
  4. When app grows, add more slices for API, Admin, etc
  5. Having business logic in app makes it easy to just use across slices, but here I would think about extracting To lib to not autoload everything.
  6. When app grows further, play with decoupling further by working with events. I would have event handlers that update different slice-based read models within those slices, but event publication can still happen from the main app.

I hope that inspires you somehow. While I got used to having business logic in thelib folder, the app folder in Hanami 2 is a very viable option for me. It is not used to read code from slices, but the ither way around (IMHO)