For complex use cases we may want to pass data to views in order to present it to our users. Hanami puts emphasis on explicitness: data isn’t shared between the controller action and the view unless we tell it to do so.

    We use a simple and powerful mechanism to achieve our goal: exposures. Each exposure first looks for a method matching the given name. If no method is found, a getter is created with #attr_reader. Only the whitelisted exposures are made available to the corresponding view.

    1. # apps/web/controllers/dashboard/index.rb
    2. module Web
    3. module Controllers
    4. module Dashboard
    5. class Index
    6. include Web::Action
    7. expose :greeting
    8. def call(params)
    9. @greeting = "Hello"
    10. @foo = 23
    11. end
    12. end
    13. end
    14. end
    15. end

    In the example above we have exposed :greeting, but not :foo. Only greeting can be used from the view and template.

    1. # apps/web/views/dashboard/index.rb
    2. module Web
    3. module View
    4. module Dashboard
    5. class Index
    6. include Web::View
    7. def welcome_message
    8. greeting + " and welcome"
    9. end
    10. end
    11. end
    12. end
    13. end

    If we try to use foo, Ruby will raise a NoMethodError.