Ri1a
Ri1a

Reputation: 743

How to access rails methods in a rails plugin

I followed this tutorial to create a rails plugin.

Section 3 explains how to add a method to string that is available anywhere in a Rails application. Now for my case, I want to be able to access rails methods in the plugin itself.

For example in lib/plugin/my_plugin/my_plugin.rb I want to use:

Rails.application.eager_load!

But every time running the gem with an executable it throws following error:

undefined method `eager_load!' for nil:NilClass (NoMethodError)

Now I know this error is thrown because there's no Rails application, but I added the plugin to a Rails application and it also doesn't seem to work (same error) and can't find another way to get this working. Am I approaching this problem the wrong way or is there even a better way?

lib/plugin/my_plugin/my_plugin.rb:

require 'rails'

class MyPlugin
  def fetch_models

    arr_models = []

    Rails.application.eager_load!

    ::ApplicationRecord.descendants.each do |model|
      arr_models[] << model
    end
  end
end

Steps reproduce:

  1. Create a new plugin rails plugin new custom
  2. Add lib/custom/generator.rb

lib/custom/generator.rb:

require 'faker'
require 'rails'

class Generator
  def fetch_models

    arr_models = []

    Rails.application.eager_load!

    ApplicationRecord.descendants.each do |model|
      arr_models[] << model
    end
  end
end
  1. Edit lib/custom.rb

lib/custom.rb:

require "custom/generator"
require "custom/version"
require "custom/railtie"

module Custom
  def self.generate
    generator = Generator.new
    models = generator.fetch_models
  end
end
  1. Add executable in bin/

bin/custom:

#!/usr/bin/env ruby

require 'custom'
Custom.generate

  1. Edit custom.gemspec so that bin/test passes
  2. Execute following commands:
$ bundle exec rake build
$ bundle exec rake install

Upvotes: 1

Views: 134

Answers (1)

Mukkoo
Mukkoo

Reputation: 76

Plugins usually are built to extend core classes. Using the generator and following the linked guide at my_plugin/lib/my_plugin/rails_core_ext.rb you have to use class you want to extend.

Your code become

class RailsPlayground::Application
  def fetch_models
    arr_models = []
    Rails.application.eager_load!
    ApplicationRecord.descendants.each do |model|
      arr_models[] << model
    end
  end
end

or

class RailsPlayground::Application
  def fetch_models
    Rails.application.eager_load!
    ApplicationRecord.descendants
  end
end

Upvotes: 1

Related Questions