I have this module:
module Moody
def foo
'bar'
end
end
And yet in a controller:
class MyController
include Moody # this works. Including Moodasdasd causes a failure
def index
puts foo #=> expect 'bar' undefined local variable or method `foo' raised
end
end
I get a undefined local variable or method error.
How should I include a module's methods in an action?
I'm guessing the module isn't being included in the application namespace?
I can't be sure without knowing where the module file is located.
Try and include the filepath in the application namespace and see if that helps.
Like in this gist: https://gist.github.com/jhjguxin/5180534
Related
How can I define a module that checks the existence of an instance method in the class the module is used. The module is normally included at the start of the file while methods are defined afterwards. I'm using Rails.
A module with a hook
module MyModule
extend ActiveSupport::Concern
included do
raise "Foo" if method_defined? :bar
end
end
A Foo error is never raised in the following code, how can I get this to raise the error?
class MyClass
include MyModule
def bar
puts "Hello from Bar"
end
end
A Foo error IS raised in the following code:
class MyOtherClass
def bar
puts "Hello from Bar"
end
include MyModule
end
This is a pure-Ruby answer. I don't know if Rails supports callbacks that are not supported by Ruby that would be useful here.
As #Amadan notes, the module is not a mind-reader; to see an instance method defined on the class the method needs to be defined before the module is included. The method Module#included takes as an argument the module in which it being included. It needs that because self is MyModule when that method is executed.
module MyModule
def self.included(mod)
puts "self = #{self}"
puts ":bar is defined" if mod.method_defined? :bar
puts ":foo is defined" if mod.method_defined? :foo
puts ":goo is defined" if mod.method_defined? :goo
end
def goo
end
end
class MyClass
def bar
end
include MyModule
end
prints
self = MyModule
:bar is defined
:goo is defined
Note that Module#included is executed after the instance method defined in MyModule (goo) is included in MyClass.
I've created a helper which I'd like to use for text manipulation
module ApplicationHelper
module TextHelper
extend ActionView::Helpers
end
end
However when I run ApplicationHelper::TextHelper.simple_format "foo" in Rails console I get
NoMethodError: undefined method `white_list_sanitizer' for Module:Class
Is there anything else I need included?
I have already looked at https://github.com/rails/rails/issues/13837 but it didn't work.
Using Rails 4, Ruby 1.9.3
If you're in the console, you should be able to just do helper.simple_format('hi'). The helper method is available in console as a way to call some helper methods.
When using a custom helper:
# app/helpers/custom_helper.rb
module CustomHelper
def custom_method(x)
puts "Custom method #{x}"
end
end
# from the console
helper.custom_method('hi')
# from the controller
class SomeController < ApplicationController
def index
view_context.custom_method('hi')
end
end
Possible Noob Warning: New to RoR
I am trying to use concerns in RoR. Right now I just have a very simple concern writen
#./app/controllers/concerns/foo.rb
module Foo
extend ActiveSupport::Concern
def somethingfoo
puts "Ayyyy! Foo"
end
end
When I try and use this concern in my controller I get a undefined method error
#./app/controllers/foo_controller.rb
class FooController < ApplicationController
include Foo
def show
Foo.somethingfoo # undefined method 'somethingfoo' for Foo:Module
render plain: "Ohh no, It doesnt even show me because of the error above me"
end
end
To my knowledge somethingfoo should be called but it is not. I have also tried defining somethingfoo in a included do ... end block in the concern but this does not work either.
Is there something I am missing? Can concerns not be used like this with controllers?
If you include modules (extended by ActiveSupport::Concern or not), the methods of that module become instance methods of the including class/module.
Your Controller method should hence read
def show
somethingfoo
render plain: "Yeah, I'm shown!"
end
File structure:
../controllers
/api
/v1
users_controller.rb
some_controller.rb
Inside users_controller.rb
module Api
module V1
class UsersController < ApplicationController
def create
return false
end
end
end
end
I can include Api in a controller and do Api::V1::UsersController. However, when I try
Api::V1::UsersController.create
in any controller I get an error:
undefined method `create' for Api::V1::UsersController:Class
I've tried doing modules in lib, but the rails 4 autoloading was being weird so I tried doing it this way, but I don't know why my methods are undefined. When I go into the console and puts Api::V1::UsersController.methods.sort, the :create method isn't there. So what am I doing wrong?
create is not a class method. It can't be called as Class.method.
You need an instance of this class to call it.
If you just want to try(though this is not the way controller work)
Api::V1::UsersController.new.create
I just stumbled over a weird problem, and I don't really understand what is causing this.
In our rails app, let's have a mixin Mixin:
module Mixin
def foo
with_scope :find => ... do
...
end
end
end
which is includeed into a model class elsewhere:
class Model < ActiveRecord::Base
include Mixin
...
end
calling Model.new.foo results in an error: NoMethodError: undefined method with_scope
I then changed the foo method to:
def foo
self.class.with_scope :find => ... do
...
end
end
But this also results in an error: NoMethodError: protected method with_scope called
This seems odd. I would have expected that the mixin methods would behave like any other method in Model. I never stumbled over this before, because all the instance methods like save are there and work as usual.
Am I doing it all wrong?