I have an engine that will be installed over an application that uses Active Admin...
After install Active Admin, I need to run my engine installer. This will create a file monkey patching an Active Admin class.
The file looks like this...
module ActiveAdmin
module Devise
# things I need to add...
end
end
So, the question is: where I need to put this file and why?
I used the Railtie's initializer method.
my_engine/lib/admin_invitable/engine.rb
module MyEngine
class Engine < ::Rails::Engine
isolate_namespace MyEngine
initializer "ativeadmin_invitable_patch" do |app|
require_relative "activeadmin_invitable_patch"
end
end
end
my_engine/lib/admin_invitable/activeadmin_invitable_patch.rb
module ActiveAdmin
module Devise
# bla bla
end
end
Related
I'm writing a Rails plugin to extend a Rails engine. Namely MyPlugin has MyEngine as a dependency.
On my Rails engine I have a MyEngine::Foo model.
I'd like to add new methods to this model so I created a file in my plugin app/models/my_engine/foo.rb which has the following code:
module MyEngine
class Foo
def sayhi
puts "hi"
end
end
end
If I enter the Rails console on the plugin dummy application I can find MyEngine::Foo, but runnning MyEngine::Foo.new.sayhi returns
NoMethodError: undefined method `sayhi'
Why MyPlugin cannot see the updates to MyEngine::Foo model? Where am I wrong?
Ok, found out. To make MyPlugin aware and able to modify MyEngine models the engine must be required on the plugin engine.rb like so:
require "MyEngine"
module MyPlugin
class Engine < ::Rails::Engine
isolate_namespace MyPlugin
# You can also inherit the ApplicationController from MyEngine
config.parent_controller = 'MyEngine::ApplicationController'
end
end
In order to extend MyEngine::Foo model I then had to create a file lib/my_engine/foo_extension.rb:
require 'active_support/concern'
module FooExtension
extend ActiveSupport::Concern
def sayhi
puts "Hi!"
end
class_methods do
def sayhello
puts "Hello!"
end
end
end
::MyEngine::Foo(:include, FooExtension)
And require it in config/initializers/my_engine_extensions.rb
require 'my_engine/foo_extension'
Now from MyPlugin I can:
MyEngine::Foo.new.sayhi
=> "Hi!"
MyEngine::Foo.sayhello
=> "Hello!"
See ActiveSupport Concern documentation for more details.
I have alredy 3 grey hair from this. Rails4.0/ruby 1.9.3. I have file test.rb in directory /lib/moduletest/test. test.rb looks like this:
module Moduletest
class test
end
end
How can I instantiate this class in my controller? How should I use the require command? Moduletest::test.new() ?
At first may I suggest you to use "foobar" instead of "test". "test" looks really like, test.
Back to question, there are two ways to use it in controller, given you have already loaded the module correctly as per comments.
The first is to explicitly include it. Preferred
class ApplicationController < ActionController::Base
include ModuleFoo
def index
bar # Use ModuleFoo's method directly
#...
end
end
The second is to hook the extension in Rails loading
# ModuleFoo
module ModuleFoo
def bar
end
end
if defined? ActionController::Base
ActionController::Base.class_eval do
include ModuleFoo
end
end
# Controller
class SomethingController < ApplicationController
def some_method
bar # use this directly
end
end
You have to put the lib directory into your autoload path. So Rails load your file on startup:
config/application.rb and add:
config.autoload_paths += %W(#{config.root}/lib)
What is the proper syntax to nest child modules within a parent module that is being is an isolate_namespace Rails engine gem?
# lib/myengine/engine.rb
module MyEngine
class Engine < Rails::Engine
isolate_namespace Myengine
# def ...
end
end
For example. The parent module is MyEngine and the child module is Blog. MyEngine will share common domain, like CRUD, Taggable, Searchable, etc, which will keep the gem code DRY and isolated from the main app (MyApp), while inheriting the isolated namespace and Engine.
Are either of the two approaches correct? Any refactor advice?
# A
# lib/myengine/blog.rb
module MyEngine
module Blog
# def ...
end
end
# B
# lib/myengine/blog.rb
module MyEngine
class Engine < Rails::Engine
isolate_namespace Myengine
module Blog
# def ...
end
end
end
Option A. is correct, but it should be lib/my_engine/blog.rb. You can read more about Ruby & Rails naming conventions here.
Further, if you want to put more modules or classes under the blog namespace you put them in the folder lib/my_engine/blog and nest them under MyEngine::Blog.
I want to create a gem which adds some functionality to my models. How to define a custom keyword for a Mongoid model? E.g.:
class Book
include Mongoid::Document
has_my_awesome_functionality
end
If you have a gem called foobar you can put the following into your gem's initialiser, or in a separate file (usually called railtie.rb[, just make sure it's being loaded]):
require 'foobar'
require 'rails'
class FooBar
class Railtie < Rails::Railtie
config.before_initialize do
::Mongoid::Document.module_eval do
def self.included(base)
base.extend FooBar::MongoidExtension
end
end
end if defined?(Mongoid)
end
and your extension can look like this:
module Foobar::MongoidExtension
def has_my_awesome_functionality
# logic here
end
end
I have found a lot of information about adding form helper methods (see one of my other questions), but I can't find anything about adding helper methods as if they were defined in application_helper.rb.
I've tried copying application_helper.rb from a rails app into the gem but that didn't work.
I've also tried:
class ActionView::Helpers
..but that produces an error.
Create a module somewhere for your helper methods:
module MyHelper
def mymethod
end
end
Mix it into ActionView::Base (such as in init.rb or lib/your_lib_file.rb)
ActionView::Base.send :include, MyHelper
To extends #sdbrown's excellent Answer to Rails 4:
# in in lib/my_rails_engine.rb
require 'my_rails_engine/my_rails_helper.rb'
require 'my_rails_engine/engine.rb'
And
# in lib/my_rails_engine/engine.rb
module MyRailsEngine
class Engine < ::Rails::Engine
initializer "my_rails_engine.engine" do |app|
ActionView::Base.send :include, MyRailsEngine::MyRailsHelpers
end
end
end
and finally
# in lib/my_rails_engine/my_rails_helper.rb
module MyRailsEngine
module MyRailsHelpers
# ...
def your_helper_here
end
end
end