How to use polymorphic_path in lib/module in Rails 4 - ruby-on-rails

I want to call polymorphic_path in a helper module located at lib/my_module.rb.
I tried the following from this answer, which works in a model, but not in my module:
module MyModule
include ActionDispatch::Routing::PolymorphicRoutes
include Rails.application.routes.url_helpers
def link(model)
polymorphic_path(model)
end
end
I get:
undefined method `polymorphic_path' for MyModule:Module
Btw, I load my module through config.autoload_paths += %W(#{config.root}/lib) in config/application.rb.

Turns out you have to create a class to properly include stuff in ruby, for example:
class MyClass
include ActionDispatch::Routing::UrlFor
include Rails.application.routes.url_helpers
def link(model)
polymorphic_path(model)
end
end

Related

uninitialized constant Admin::ModeratorsController::ModeratorInteractor

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.

Rails mixins using ActiveSupport::Concern does not work

I have the following module/class defined in my lib folder
module Service::Log
extend ActiveSupport::Concern
module ClassMethods
def logger
Rails.logger
end
end
end
class Service::MyService
include Service::Log
end
When I try to invoke logger method via an object instance I get an error message - NoMethodError: undefined method `logger' for - Service::MyService:0x007fdffa0f23a0
Service::MyService.new.logger
What am I doing wrong? I am using Rails 4.0.2.
You are defining the logger method as a class method, instead of a normal method. This should work:
module Service::Log
extend ActiveSupport::Concern
def logger
Rails.logger
end
end
class Service::MyService
include Service::Log
end
Service::MyService.new.logger
The way you were defining the method before allowed you to use the logger method on the class directly, such as:
Service::MyService.logger

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)

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.

Adding a helper method with a gem

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

Resources