uninitialized constant Admin::ModeratorsController::ModeratorInteractor - ruby-on-rails

Hi i am working on a RoR project with ruby-2.3.0 and rails 4. I am trying to call a method of interactor from controller. My controller is inside the Admin directory as follows:
class Admin::ModeratorsController < Admin::ApplicationController
include Interactor
def index
ModeratorInteractor.find_abc(params)
end
end
My interactor is:-
# frozen_string_literal: true
class ModeratorInteractor
def self.find_abc(params)
User.all
end
end
When i run my code i got an error uninitialized constant Admin::ModeratorsController::ModeratorInteractor.
I also try to include the Interactor:-
include Interactor
Please help how to fix it.Thanks in advance.

You need to define ModeratorInteractor as module to include it in your controller:
module ModeratorInteractor
def self.find_abc(params)
User.all
end
end
Then you need to ensure that the module is loaded properly:
# in application.rb
config.autoload_paths += %W("#{config.root}/lib") # path to your module
Or you can also use require instead of autoload_paths:
require "#{Rails.root}/lib/modeator_interactor"
Then in your controller, you can include it:
include ModeratorInteractor

First, you need to include Interactor in your ModeratorInteractor, also you need to define a call method, not find_abc which will not work and it will throw and error of undefined method, so your final interactor will look like this
# frozen_string_literal: true
class ModeratorInteractor
include Interactor
def self.call
params = context.params
end
end
and you will call it as
ModeratorInteractor.call(params: params)
Voila.

Related

Extending Rails flash

I have in app/lib/action_dispatch/flash/flash_hash.rb file this code:
class ActionDispatch::Flash::FlashHash
def my_method
#...
end
end
but when I call it in controller, I get undefined method 'my_method' for ActionDispatch::Flash::FlashHash:0x007fcf8e81e510:
def index
flash.my_method
end
Why? Any ideas?
Thanks
You need to require the file on startup, try using an initializer:
# config/initializers/flash_monkeypatch.rb
require "#{Rails.root}/lib/action_dispatch/flash/flash_hash"
And restart your app.

Rails 4 trouble using module in controller

In my rails 4 app I'm having trouble extracting the twitter gem config from my controller to a module, getting
undefined method `include' for #<UsersController:0x007ff7d566df08>
Users_controller.rb
def show
include Twitconfig
...
end
controllers/concerns/Twitconfig.rb
require 'twitter'
module Twitconfig
#client = Twitter::REST::Client.new do |config|
...
end
end
I've tried moving the "include Twitconfig" to out of the new action like so
class UsersController < ApplicationController
include Twitconfig
but that just gave an undefined method error when calling #client.
This is my first time including a module in rails 4 and I've been trying for a while so any help would be really appreciated.
The problem is your module not the way you include it, you cannot write code outside a method.
Include will add instance method to a class, so you should try with :
require 'twitter'
module Twitconfig
def client
client = Twitter::REST::Client.new do |config|
...
end
end
end
And in your controller :
class UsersController < ApplicationController
include Twitconfig
def show
puts "#{client.inspect}
end
It should display your client

How to use created module in controller

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)

How can I extend ApplicationController in a gem?

I thought I'd come up with a slick way to extend ApplicationController in a Rails 3.x gem.
In my gem's lib/my_namespace/my_controller.rb, I had:
class MyNamespace::MyController < ApplicationController
before_filter :some_method
after_filter :another_method
def initialize
# getting classname of the subclass to use for lookup of the associated model, etc.
# and storing the model_class in an instance variable
# ...
end
# define :some_method, :another_method, etc.
# ...
private
attr_accessor :subclass_defined_during_initialize # etc.
# etc.
end
but when the Gem is loaded, app/controllers/application_controller.rb is not yet loaded, so it fails:
/path/to/rvm/gemset/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:251:
in `require': cannot load such file -- my_gem_name/application_controller (LoadError)
As a workaround, I had defined ApplicationController in my gem's lib/gem_namespace/application_controller.rb as:
class ApplicationController < ActionController::Base
end
I assumed that even though I had defined it there, it would be redefined in my Rails 3 application's app/controllers/application_controller.rb, such that both controllers in the application that extended ApplicationController and controllers that extended MyNamespace::MyController would directly or indirectly extend the ApplicationController defined in app/controllers/application_controller.rb.
However, we noticed that after loading the gem, controllers that extend ApplicationController were unable to access methods defined in app/controllers/application_controller.rb. Also, the ApplicationHelper (app/helpers/application_helper.rb) module was no longer being loaded by other helper modules.
How can I extend ApplicationController within the controller in my gem for the purpose of defining a before_filter and after_filter to and use initialize to access the class's name to determine the associated model's class that it could then store and use within its methods?
Update 2012/10/22:
Here's what I came up with:
In lib/your_gem_name/railtie.rb:
module YourGemsModuleName
class Railtie < Rails::Railtie
initializer "your_gem_name.action_controller" do
ActiveSupport.on_load(:action_controller) do
puts "Extending #{self} with YourGemsModuleName::Controller"
# ActionController::Base gets a method that allows controllers to include the new behavior
include YourGemsModuleName::Controller # ActiveSupport::Concern
end
end
end
and in lib/your_gem_name/controller.rb:
module YourGemsModuleName
module Controller
extend ActiveSupport::Concern
# note: don't specify included or ClassMethods if unused
included do
# anything you would want to do in every controller, for example: add a class attribute
class_attribute :class_attribute_available_on_every_controller, instance_writer: false
end
module ClassMethods
# notice: no self.method_name here, because this is being extended because ActiveSupport::Concern was extended
def make_this_controller_fantastic
before_filter :some_instance_method_available_on_every_controller # to be available on every controller
after_filter :another_instance_method_available_on_every_controller # to be available on every controller
include FantasticStuff
end
end
# instance methods to go on every controller go here
def some_instance_method_available_on_every_controller
puts "a method available on every controller!"
end
def another_instance_method_available_on_every_controller
puts "another method available on every controller!"
end
module FantasticStuff
extend ActiveSupport::Concern
# note: don't specify included or ClassMethods if unused
included do
class_attribute :class_attribute_only_available_on_fantastic_controllers, instance_writer: false
end
module ClassMethods
# class methods available only if make_this_controller_fantastic is specified in the controller
def some_fanastic_class_method
put "a fantastic class method!"
end
end
# instance methods available only if make_this_controller_fantastic is specified in the controller
def some_fantastic_instance_method
puts "a fantastic instance method!"
end
def another_fantastic_instance_method
puts "another fantastic instance method!"
end
end
end
end
For this specific kind of functionality I would recommend creating a module in your gem and include that module in your Application Controller
class ApplicationController < ActionController::Base
include MyCoolModule
end
To add before filters, etc (add this to your module)
def self.included(base)
base.send(:before_filter, my_method)
end
Update: you may be able to just do base.before_filter :my_method which is cleaner.
Here is a Gist
that shows how to access the class of the subclass and store it in an instance variable and access it in the before and after filters. It uses the include method.
Truth is much much simpler and flexible.
Add to lib/engine.rb this: class Engine < Rails::Engine; end
And then simply use:
ActionController::Base.class_eval do
include SomethingFromMineGemModule
# or:
def hello_from_gem
'Hey people!'
end
end
I was able to reference ApplicationController with an initializer callback.
gem code that subclasses/references ApplicationController:
class GemApplicationController < ApplicationController
before_filter :method_to_call
def method_to_call
#your code here
end
end
gem code callback to create subclassed controller:
module GemName
def self.load_gem_application_controller
require "path/to/gem_application_controller"
end
end
rails_app/config/initializers/gem_name.rb
GemName.load_gem_application_controller
Then have controllers that use this functionality subclass GemApplicationController
class SpecialCaseController < GemApplicationController
# this will inherit from the gem's controller,
# which inherits from the rails_app ApplicationController
end

Rails 3- Plugin returns 'undefined local variable'

I have a custom plugin (I didn't write it) that is not working on rails 3, however it did work with rails 2. It is for a custom authentication scheme, here is what the main module looks like:
#lib/auth.rb
module ActionController
module Verification
module ClassMethods
def verify_identity(options = {})
class_eval(%(before_filter :validate_identity, :only => options[:only], :except => options[:except]))
end
end
end
class Base
#some configuration variables in here
def validate_identity
#does stuff to validate the identity
end
end
end
#init.rb
require 'auth'
require 'auth_helper'
ActionView::Base.send(:include, AuthHelper)
AuthHelper contains a simple helper method for authenticating, base on a group membership.
When I include 'verify_identity' on an actioncontroller:
class TestController < ApplicationController
verify_identity
....
end
I get a routing error: undefined local variable or method `verify_identity' for TestController:Class. Any ideas how I can fix this? Thanks!
It worked in 2.3 because there was an ActionController::Verification module back there. It's not working in 3.0 because this module doesn't exist. Rather than relying on Rails to have a module that you can hook into, define your own like this:
require 'active_support/concern'
module Your
module Mod
extend ActiveSupport::Concern
module ClassMethods
def verify_identity(options = {})
# code goes here
end
end
end
end
and use:
ActionController::Base.send(:include, Your::Mod)
To make its functions available. ActiveSupport::Concern supports you having a ClassMethods and InstanceMethods module inside your module and it takes care of loading the methods in these modules into the correct areas of whatever the module is included into.

Resources