1

In my rails 4 app, I have a subfolder logic in my App folder, where I put classes/methods that don't belong to controllers or models.

However, when I try to access these methods from a controller, I get an unknown method error.

Here is a class in the logic folder:

class Analyze        
  def intent_determination(msg, context)
    keywords = [["categories", "category"], ["brands", "brand"], ["stock", "stocks"], ["info", "information"], ["no"], ["yes"]]
    tokenized_array = msg.split
    keywords.each {|array| context["intent"] = array.first if (tokenized_array & array).any? }
    context
  end

  def update_context(msg, session)
    session.update(context: intent_determination(msg, session.context))
    session.update(context: brand_determination(msg, session.context))
    session.update(context: style_determination(msg, session.context))
    session
  end
end

How can I access these methods in my controllers ? When I just execute update_context(my_message, @session), as I said, I get an unknown method error.

Here is my App folder structure:

App 
 Assets
 Controllers
 Logic
   analyze.rb
 Helpers
 Mailers
 Models
 Views

EDIT: I did add: config.autoload_paths << Rails.root.join('app/logic/**/') to my application.rb file.

So this is not a duplicate.

Graham Slick
  • 6,692
  • 9
  • 51
  • 87

1 Answers1

4

Your update_context method is an instance method inside the class Analyze. To invoke it, you have to do Analyze.new.update_context.

The line config.autoload_paths << Rails.root.join('app/logic/**/') you added tells Rails where to start looking for classes and modules. This means that Rails would be able to find your Analyze class just like that without you needing to do require 'some/path'.

Now, it seems like you probably want to have update_context be a class method rather than an instance method, so that you do not need to instantiate an Analyze object with Analyze.new. This is simple enough, just add self. before the method name:

class Analyze
  def self.update_context(msg, session)
  end
end

Analyze could also be a module in that case instead of a class, since an "instance" of it doesn't really seem to represent anything concrete.

Either as class or module, when defining the method as def self.update_context you'll be able to do Analyze.update_context(...) from anywhere in your app.

If you're looking for these helper methods to be used inside your views, consider defining update_context as a method inside app/helpers/application.helper.rb. Simply define it as you did (without the self.) and you'll be able to call it from any view and without any "prefix" (i.e. you'll be able to simply do update_context instead of Analyze.update_context). Rails also allows you to call such helpers from controllers (see here) and models (see here), although it would be wise to keep separation of concerns in mind (view logic stays in view helpers, persistency logic and access to data in models, and action-specific business-logic in controllers) rather than "including everything into everything" because it seems convenient.

Community
  • 1
  • 1
AmitA
  • 3,239
  • 1
  • 22
  • 31