Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails mountable engine: how should apps set configuration variables?

I have a mountable engine called Blog that apps can use.

What's the best way to allow apps that use the engine to set a configuration variable like site_name (so that the engine can display it in the design)?

Update:

I've seen some gems create a 'config/initializers/gem_name.rb' file. Is there any specification on how to:

  1. Create a file like that on the engine's side
  2. Copy it into the app's side
  3. How to access those set variables on the engine's side?

I tried creating Blog.site_name = "My Site" in the app's config/initializers/blog.rb file but get an Undefined method error.

like image 360
Hopstream Avatar asked Dec 22 '13 22:12

Hopstream


People also ask

What is configuration in Rails?

In general, the work of configuring Rails means configuring the components of Rails, as well as configuring Rails itself. The configuration file config/application. rb and environment-specific configuration files (such as config/environments/production.

How does a Rails engine work?

Rails looks first in the application's ( test/dummy ) app/views directory and then in the engine's app/views directory. When it can't find it, it will throw this error. The engine knows to look for blorgh/comments/_comment because the model object it is receiving is from the Blorgh::Comment class.

What is Mount in Rails?

Mounting rails are constructive items in electrical engineering and mechanical engineering projects; they are used to hold devices. A mounting rail is usually attached to a mounting panel or an enclosure profile.


2 Answers

Figured out an even better solution that also allows you to set default values (incase the app using the engine doesn't specify a config)...

  1. Create config variables in your app's /config/initializers/blog.rb like this:
    Blog.setup do |config|
        config.site_name = "My Site Name"
    end
  1. In your engine's /lib/blog/engine.rb set default values like this:
    module Blog
    
         self.mattr_accessor :site_name
         self.site_name = "Site Name"
         # add default values of more config vars here
    
         # this function maps the vars from your app into your engine
         def self.setup(&block)
            yield self
         end
    
    end
  1. Now you can simply access the config variables in your engine like this:

Blog.site_name

Much cleaner.

like image 155
Hopstream Avatar answered Sep 17 '22 18:09

Hopstream


I know this is a fairly old post, but in the event someone in the future finds this, I'd like to recommend the Angostura gem for passing dependencies into a Rails engine. To use it, assuming my engine is called 'Blog' and I want to access a variable called 'site_name', the engine's lib/blog.rb looks something like:

require "blog/engine"
require "angostura"

module Blog
  include Angostura::Dependencies

  dependency :site_name
end

In my main app, in config/initializers/blog.rb, I added

Blog.setup do |config|
  config.site_name = "My site name"
end

Now, I can access site_name in my engine by calling Blog.site_name.

I'd like to point out that defaults are also supported, so you could do something like dependency site_name: 'Default site name' in lib/blog.rb. Furthermore, you can pass in whole classes as dependencies by sending it stringified classnames, like config.my_class = 'MyClass'.

For posterity, in order to use the gem, I added s.add_dependency "angostura", "0.6.0" in my engine's gemspec, and then ran bundle install.

like image 41
G Klausner Avatar answered Sep 17 '22 18:09

G Klausner