mbajur
mbajur

Reputation: 4474

Internal rails notifications

I'm creating an rails app, which imports some stuff from external service. At the end of that import, user should get an info about how many new items has been imported (it's like a periodical check, which adds just new items to local database. Not all of them each time.). A whole process and method-chain is quite complex so i'm looking for a best-practice on how to pass such information from deeply nested method. Schema looks more or less like that:

some_controller.rb
  -> Model.method()
    -> Lib1.method1()
      -> Lib2.method2()
        -> Lib3.method3()
          -> Lib4.method4()
            -> Lib5.method5()
              -> items_import_method()

and i need to somehow pass info about how many new items has been imported from items_imported_method() to some_controller.rb (or any other place this import is fired). The most obvious way of doing that is passing new_items_count var all the way up though this whole method chain but it seems a bit wrong to me. Isn't there any better way?

I was thinking about some kind of internal events/messages system which would let me to subscribe to some custom channel, like activeresource events but maybe there is some well-known and suggested approach for such situation?

Thanks in advance.

Upvotes: 0

Views: 40

Answers (1)

tadman
tadman

Reputation: 211540

One way to tackle this is to create some kind of context container object that has properties any of those steps can manipulate, then pass this in to each method on the way down.

For example:

class ContextExample
  attr_accessor :example_field
end

In practice:

@context = ContextExample.new

Lib1.method1(@context)

@context.example_field
# => "Test!"

Where what you're doing is:

module Lib1
  def self.method1(context)
    Lib2.method2(context)
  end
end

module Lib2
  def self.method2(context)
    context.example_field = "Test!"
  end
end

These modules or classes can save context if required, and pass it on when necessary.

If you have well-defined properties you need to set and manipulate, a class with attr_accessor for those usually works pretty well. If it's a more arbitrary thing and you're not sure what might shake out in the end, either use a Hash or an OpenStruct object to capture whatever might come up.

Upvotes: 2

Related Questions