3

I wish to make a custom method (e.g. def plus_two(x) x + 2 end and have it be accessible everywhere within the app - that is, accessible in the controller, model, console, views, tests, and any other .rb files. I currently have the same method defined in many areas of the app, and wish to make it DRY

How can this be achieved?

Note: I don't mind if calling the method requires prepending something (I have seen some answers where methods are prepended with :: or with a namespace, but otherwise have a preference to keep code succinct where possible

I have done some reading at similar questions (e.g. this one) but I can't quite get it

stevec
  • 41,291
  • 27
  • 223
  • 311
  • I would go for a helper for a controller or a concern for models. If you still need all around the app you can make a singleton. edit: im not the one who downvote. – Marcelo Fonseca Feb 01 '19 at 19:23
  • maybe this post can help you achieve this https://stackoverflow.com/questions/10762246/how-do-i-create-a-singleton-global-object-in-rails – Marcelo Fonseca Feb 01 '19 at 19:26
  • Thanks for the tips. Is it possible to list the steps, i.e. each file I need to make, what to put in each file, and any commands to run? I asked the same question as above in a forum and 90 messages later I still can not determine a way to do what I want to do. I learned of the existence of stubs, fixtures, services, instance vs class methods, and a few other things, but still no luck with clear and complete instructions – stevec Feb 01 '19 at 19:28
  • Possible duplicate of [Auto-loading lib files in Rails 4](https://stackoverflow.com/questions/19098663/auto-loading-lib-files-in-rails-4) – max pleaner Feb 01 '19 at 19:35
  • It's might not strictly be a duplicate of that question but you can use that answer. Add lib/ to the autoload paths and put any custom classes in the lib/ folder. You can alternatively use any files in `config/initializers` – max pleaner Feb 01 '19 at 19:37
  • 2
    I don't know Rails, but considering that `Object.ancestors #=> [Object, Kernel, BasicObject]` you could add it to the `Kernel` module. – Cary Swoveland Feb 01 '19 at 20:16
  • 2
    If you don't mind the "namespace" (which would be preferable IMO) then something as simple as `module Thing; def self.plus_two(x); x + 2; end; end` would work and you just call it as `Thing.plus_two(4) #=> 6` – engineersmnky Feb 01 '19 at 20:41
  • can you share the method... In general, you wouldn't want to do what you're asking. – Sebastian Scholl Feb 01 '19 at 22:20

1 Answers1

6

Reading the comments it seems like you are just looking for a clear and simple example of a method that is available everywhere in your application:

# in app/models/calculator.rb
module Calculator
  def self.plus_two(x) 
    x + 2 
  end
end

Which can be called like this:

Calculator.plus_two(8)
#=> 10
spickermann
  • 100,941
  • 9
  • 101
  • 131
  • 2
    Being able to do this is a major break through for me (I had read 90+ forum posts and about 20 SO questions and not been able to do it prior to asking). A follow up question, instead of the 1 method, say I had 10 that I wanted to define, would I put them all into separate files (e.g. `calculator.rb`, `abacus.rb` etc etc) or can I somehow put multiple methods in one file? What is best practice? – stevec Feb 02 '19 at 03:25
  • 2
    @user5783745 yes! You can put multiple methods in the same module and make more modules as well. Do you understand the difference between a class and a module? You may find in some cases that you want to use a class instead of a module. Additionally, you may want to look into ActiveSupport Concerns, which is the Rails way to “mix in” functionality into classes. They’re handy if you have functionality that you want to include into multiple models. https://api.rubyonrails.org/classes/ActiveSupport/Concern.html – Nate Feb 02 '19 at 04:17
  • 2
    @user5783745 : It is possible to add more methods to such a module and you can have more than one module. In this approach, I would use different modules to group methods to have them organized. Having too many methods in one file is hard to read and hard to understand. You might want to organize methods by their purpose or by the datatype they are handling. But such a structure totally depends on our application and your domain. – spickermann Feb 02 '19 at 04:41