Rails: same name for library module and group of controllers?

I am organizing my code, so far I have managed to group controllers/helpers/views into β€œadmin” folders, but initially I had a library with the same module name β€œadmin”, m can no longer call. (name of conflict?)

New structure:

 Directory Structure -> app -> controllers -> admin #new -> admin_main -> admin_permissions -> Helpers -> admin #new -> admin_main_helper -> admin_permissions_helper -> lib -> admin -> pagerduty.rb 

Previously, I could call my library from my helpers as follows:

 module Admin::AdminMainHelper #admin:: is new require "./lib/admin/pagerduty.rb" def pager_duty pagerduty = Admin::PagerDuty.new() #throws error after the new structure @on_call = pagerduty.first_on_call() @counts = pagerduty.open_incidents() end end 

Error "uninitialized constant Admin::PagerDuty"

Do I need to rename my library to something else? or is there a way around this?

EDIT: It works if I rename my library module to "AdminLib" instead of "Admin", for example. So the question is, is there a way around this.

+4
source share
2 answers

I think the problem is the download path. I think require should be:

 require "#{Rails.root}/lib/admin/pagerduty.rb" 

Another solution, albeit a bit hard, is to load all the lib subdirectories into LOAD_PATH , for example:

In application.rb for config.autoload_path :

 config.autoload_paths += Dir["#{config.root}/lib/**/"] 
+2
source

To require the correct path dependency in Ruby , you should:

  • rename pagerduty.rb => pager_duty.rb
  • required: require 'admin/pager_duty'

This is possible because Rails is already adding your lib folder to your LOAD_PATH. This is great for producing ready-made code (usually libraries).

But if you want to develop your lib files in development - without having to restart the server every time you make changes, you can change your setting as follows:

  • add this line to you config/application.rb :

    config.autoload_paths + =% W (# {config.root} / lib)

  • remove any explicitly required lib file statements inside controllers or models (any application file / *)

This will work well. But this is a common antipattern . Because:

  • The lib code must be completely independent of your application so that you can share it between applications. And if you use the startup mechanism, it means that he is a first-class citizen of your application. In this case, it is much better to configure a new folder inside the application (for example, the application / tools) and configure autoload for it. Otherwise, you may get a cluttered lib folder filled with application-specific code. More details here .

  • Autoload will not work for classes that are already defined or defined in several places (e.g. monkeypatches). More here

+3
source

Source: https://habr.com/ru/post/1497459/


All Articles