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
Related
I want to make a small code refactor and extract client external client from gem to a separate module (it's use to connect to the DatoCMS API via gem 'dato'). My standard class, which works well, look like:
app/services/receive_webhook/fetch_model_name.rb
module ReceiveWebhook
class FetchModelName
def initialize(model_id)
#model_id = model_id
end
def call
fetch_model(#model_id).dig('name')
end
private
def client
#client ||= Dato::Site::Client.new(Rails.application.credentials.datocms_api_token)
end
def fetch_model(model_id)
client.item_types.find(model_id)
end
end
end
I want to separate client method to a different module and include it in FetchModelName class (like in standard Rails app). To do so I use below code:
app/dato_cms_api/dato_client.rb
module DatoCmsApi
module DatoClient
def client
#client ||= Dato::Site::Client.new(Rails.application.credentials.datocms_api_token)
end
end
end
With updated FetchModelName class:
app/services/receive_webhook/fetch_model_name.rb
module ReceiveWebhook
class FetchModelName
include ::DatoClient
def initialize(model_id)
#model_id = model_id
end
def call
fetch_model(#model_id).dig('name')
end
private
def fetch_model(model_id)
client.item_types.find(model_id)
end
end
end
But I'm getting an error:
Zeitwerk::NameError - expected file app/dato_cms_api/dato_client.rb to define constant DatoClient, but didn't:
app/services/receive_webhook/fetch_model_name.rb:5:in `<class:FetchModelName>'
app/services/receive_webhook/fetch_model_name.rb:4:in `<module:ReceiveWebhook>'
app/services/receive_webhook/fetch_model_name.rb:3:in `<main>'
app/controllers/api/v1/webhooks/dato_cms/receive_webhook.rb:29:in `block in <class:ReceiveWebhook>'
Does Grape API not support include module practice?
Did you try to downgrade your autoloader to classic?
In your application.rb file, add this:
config.autoloader = :classic
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.
I have created a concern in controllers/concerns called reports.rb
In it I created the ClassMethods module.. It looks like this
module Reports
extend ActiveSupport::Concern
included do
require 'peddler'
require 'csv'
end
module ClassMethods
def report_details(token, marketplace_id, merchant_id)
#...
end
I included this concern in my Merchants controller like this:
class MerchantsController < ApplicationController
include Reports
And then tried to call the report_details method in an action on the Merchants controller like so:
def pull_from_amazon
me = Merchant.find(params[:merchant_id])
marketplace = me.marketplace
token = me.token
Merchant.report_details(token, marketplace, params[:merchant_id])
redirect_to root_path
end
According to this post Rich on Rails I should be able to call:
Merchant.report_details(xx,xxx,xxxx)
But I get a NoMethodError when I try.. I also tried:
me.report_details(xx,xxx,xxxx)
And got the same NoMethodError
What did I do wrong?
Try this
MerchantController.report_details(xx,xxx,xxxx)
But you should better include this concern in model.
I want to add a filter to the ApplicationController but I want to do it within my gem.
What I want to avoid is the following:
class ApplicationController < ActionController::Base
include MyGem
end
I do not want that. I don't want to have to include my module in the source code.
I am having issues though.
Here is the relevant code:
lib/correlation_id/controller_extension
module CorrelationId
module ControllerExtension
def self.included(klass)
klass.class_eval do
after_filter :pass_correlation_id
end
end
def pass_correlation_id
correlation_id = request.headers['Correlation-ID'] || SecureRandom.uuid
headers['Correlation-ID'] = correlation_id
end
end
end
ApplicationController.send :include, CorrelationId::ControllerExtension
lib/correlation_id.rb
require 'correlation_id/controller_extension'
module CorrelationId
end
Now, when I'm in the test/dummy directory, which is a test rails app for my gem, I try to boot up the server using rails s and I get the following error:
/correlation_id/lib/correlation_id/controller_extension.rb:17:in `<top (required)>': uninitialized constant ApplicationController (NameError)
I'm clearly having problems with referencing ApplicationController to monkey-patch it.
How would I manage this? I want my gem to be self-contained.
The following code works. What I did was prematurely create ApplicationController with the appropriate inheritance. Note, many people use the rails-api gem, so I factored in them to ensure the fact that it would work.
Also, note: You must inherit from a class because otherwise ApplicationController will be a usual class that doesn't understand what after_filter is.
module CorrelationId
module ControllerExtension
def self.included(klass)
klass.class_eval do
after_filter :pass_correlation_id
end
end
def pass_correlation_id
correlation_id = request.headers['Correlation-ID'] || SecureRandom.uuid
headers['Correlation-ID'] = correlation_id
end
def self.base_controller_inheritance
if Gem::Specification.find_all_by_name('rails-api').any?
ActionController::API
else
ActionController::Base
end
end
end
end
class ApplicationController < CorrelationId::ControllerExtension.base_controller_inheritance
include CorrelationId::ControllerExtension
end
I imagine there might be a better way to check if they are using ActionController::API and if so, please do share, but as of now, this seems like the most solid way to do it.
I have a controller that calls a model method:
class WelcomeController < ApplicationController
item_num = params[:item_num] || "0001"
#product = Scraper.lookup_item(item_num)
end
Here is the Scraper model:
class Scraper < ActiveRecord::Base
require 'nokogiri'
require 'mechanize'
def self.lookup_item(item_num)
# code goes here
end
end
Why am I getting this error?
NoMethodError: undefined method 'lookup_item' for Scraper:Module
I have run into this error before. grep your project to see if module Scraper is defined anywhere. If it is, remove it, or change it to class instead of module.