usabilityhub / rails-erb-loader

Embedded Ruby (.erb) webpack loader for Ruby projects.
MIT License
103 stars 28 forks source link

How to access controller methods in erb file? #116

Open chipit24 opened 2 years ago

chipit24 commented 2 years ago

I have a controller at lib/my_awesome_helpers/controller.rb that looks something like this:

module MyAwesomeHelpers
  module Controller
    def print_some_stuff
      return 'some stuff'
    end
  end
end

I set up my webpack.config.js file with the following options:

  /* ... */
  module: {
    rules: [
      {
        test: /\.js\.erb$/,
        enforce: 'pre',
        loader: 'rails-erb-loader',
      },
      /* ... */

And here is my frontend/lib/testing.js.erb file:

console.log(<%= not Rails.env.production? %>); // this works fine, logs false
console.log('<%= MyAwesomeHelpers::Controller.print_some_stuff %>'); // this causes an error

My setup works great, however, when I try to access any of my controller methods, I get the following error when I run my webpack build:

Traceback (most recent call last):
  13: from ./bin/rails:4:in `<main>'
  12: from ./bin/rails:4:in `require'
  11: from /Users/[...]/.rvm/gems/ruby-2.7.6@my_awesome_project/gems/railties-6.1.5.1/lib/rails/commands.rb:18:in `<top (required)>'
  10: from /Users/[...]/.rvm/gems/ruby-2.7.6@my_awesome_project/gems/railties-6.1.5.1/lib/rails/command.rb:48:in `invoke'
  9: from /Users/[...]/.rvm/gems/ruby-2.7.6@my_awesome_project/gems/railties-6.1.5.1/lib/rails/command/base.rb:69:in `perform'
  8: from /Users/[...]/.rvm/gems/ruby-2.7.6@my_awesome_project/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
  7: from /Users/[...]/.rvm/gems/ruby-2.7.6@my_awesome_project/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
  6: from /Users/[...]/.rvm/gems/ruby-2.7.6@my_awesome_project/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
  5: from /Users/[...]/.rvm/gems/ruby-2.7.6@my_awesome_project/gems/railties-6.1.5.1/lib/rails/commands/runner/runner_command.rb:42:in `perform'

ERROR in ./lib/testing.js.erb
Module build failed (from ../node_modules/rails-erb-loader/index.js):
Error: rails-erb-loader failed with code: 1
    at ChildProcess.<anonymous> (/Users/[...]/Code/my_awesome_project/node_modules/rails-erb-loader/index.js:128:16)
    at ChildProcess.emit (events.js:198:13)
    at maybeClose (internal/child_process.js:982:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:259:5)

Any idea on how to get this working?

rhys-vdw commented 2 years ago

Hm, my Ruby is rusty...

module MyAwesomeHelpers
  module Controller # I don't know what this line does

  def print_some_stuff
    return 'some stuff'
  end
end

Should this not be:

module MyAwesomeHelpers
  module Controller

    def Controller.print_some_stuff
      return 'some stuff'
    end
  end
end
PikachuEXE commented 2 years ago

Ya but normally we use self.method not Modulename.method


module MyAwesomeHelpers
  module Controller

    def self.print_some_stuff
      # Do you need `return`?
      return 'some stuff'
    end
    # or
    # Not sure if this works in module (that's is not a class)
    class << self
      def print_some_stuff
        # Do you need `return`?
        return 'some stuff'
      end
    end
  end
end
chipit24 commented 2 years ago

@rhys-vdw The controller is set up correctly, I redacted the details of the controller and made a mistake with the nesting when writing it here, thanks for catching that! But my Ruby is very rust right now as well 😅

@PikachuEXE I can give that a try, thanks!

One thing to note about this controller is that its methods are used in a "regular" view file at app/views/layouts without issue–so I don't think there's anything really wrong with the controller itself. I'm only having issues accessing those helper methods in my .js.erb file using rails-erb-loader.

rhys-vdw commented 2 years ago

Well controller instances are only created in response to a request, so they won't exist at build time. This is why I was trying to make sense of your code example. Anything that is global should be available to rails-erb-loader. An easy way to test if this is true is to open up the Rails REPL and see if your Ruby works. If your code works there then it should work in the template.