Rails where is 'mail' method defined - ruby-on-rails

If I know the class name I can do something like TheClassName.method(:mail).source_location but I don't know the class name the method belongs to.
Where is 'mail' defined? method(:mail) raises
NameError: undefined local variable or method `mail' for main:Object
but its written just as mail(*args, &block) in the code.

bundle open rails was not particularly helpful as there was just a readme...
going up a directory and rummaging around I stumbled across actionmailer directory.
Its in ActionMailer::Base, but unless you know that in advance, I don't know how you would search for it

Related

Ruby gem won't add method to global scope using extend

I am trying to write a Ruby Gem which, when required, adds a function to the global scope.
I have followed the ideas here:
How can I add a method to the global scope in Ruby?, however, it just doesn't work! (on Ruby 2.4.3 anyway)
Here is my actual source code, but the below also summarises what I've done and what isn't working:
# example.rb
module Example
def self.hello()
puts "Hello"
end
end
extend Example
Then
# app.rb
require 'example' # Having built as a gem
hello() #=> `<main>': undefined method `hello' for main:Object (NoMethodError)
Where did I go wrong?
Sergio solved this for me, though I don't quite understand how!
It was considered good practice to encapsulate the methods in a module, so that users of the gem can use them directly (hello) or scoped (Example::hello) as they pleased.
By removing self. the method can be accessed directly only. By including self. it doesn't work at all. However, by doing:
module Example
extend self
def hello
puts "Hello"
end
end
extend Example
...it does work in both ways.

ruby on rails constantize method

I came across the following in the model:
class Search < ActiveRecord::Base
#search different system user by dn
def self.gets(sys, dn)
sys.constantize.search(dn)
end
end
I can see the purpose is to pass in different model name as sys and search by dn in those specific models. However, I searched on constantize in Ruby and couldn't see any detailed explanation about this usage.
Rails documentation (because constantize is a Rails method) says:
Tries to find a constant with the name specified in the argument
string.
For instance, if you have a model called Foo in your application, then you can apply the constantize method to a string, which contains the exact word Foo, and it'll give you a new object with this model. Note this must be capitalized as Rails would work with your model, if you do a bad reference, then you'll get a NameError error:
NameError: wrong constant name foo
How does it do it?, if you go to the method definition, or if you playing with the method get an error, you'll see the source points to activesupport-5.1.5/lib/active_support/inflector/methods.rb:269:in 'const_get', which is the method definition and the error source.
Between the cases the method handles internally depending on what's being received as argument, you'll see the Object.const_get(string) which is the way Ruby (pure) handles a "constantiz-ation", which would be the same as doing
Object.const_get('Foo') # Foo(...)
Object.const_get('foo') # NameError: wrong constant name foo
If thinking on implement this handy method, you could take a look to the Gavin Miller's post from some years ago.
When I type 'foo'.constantize in my editor (RubyMine) and tap Ctrl+B, it takes me to the source, .../activesupport-4.2.8/lib/active_support/core_ext/string/inflections.rb, with this comment:
# +constantize+ tries to find a declared constant with the name specified
# in the string. It raises a NameError when the name is not in CamelCase
# or is not initialized. See ActiveSupport::Inflector.constantize
#
# 'Module'.constantize # => Module
# 'Class'.constantize # => Class
# 'blargle'.constantize # => NameError: wrong constant name blargle
def constantize
ActiveSupport::Inflector.constantize(self)
end
It probably eventually calls Object.const_get(). I recommend you get a better editor, with code browsing, and you start learning your way around the Rails source code.

uninitialized constant while calling worker method in sidekiq

I am using sidekiq gem in rails 3 and I have define a foo_workers.rb in app/workers folder, when I try to call FooWorker.perform_async(#article) in a rails controller named articles I get this error,
uninitialized constant ArticlesController::FooWorker
Can anyone please help me.
Check your pluralization. The file is called foo_workers.rb, which means you're probably defining FooWorkers, not FooWorker. It should be singular. But this is all guessing because you didn't actually post any code.
The autoload mechanism won't pluralize your class names. So the class FooWorker is expected to be defined in a foo_worker.rb file in some of the autoload paths.
If the file name is different (like foo_workers.rb), Rails won't try to load the class from it.

My first RoR Gem: NameError in MicropostsController#up_vote uninitialized constant VoterLove::Voter::Vote

I'm working on my first RubyGem voter_love. When I install the Gem and use the up_vote method I get this error:
NameError in MicropostsController#up_vote
uninitialized constant VoterLove::Voter::Vote
Do I need to generate an initializer or require the Gem somewhere in my code to initialize the Votes model?
From here, your model is VoterLove::Votes not VoterLove::Voter::Vote.
And a simple advice: simply adopt a normal Rails app architecture and use the Engine power to have everything painlessly included (models, controllers, views...).
You've most likely referred to a class or module that doesn't exist. Most likely, you've forgotten to require a gem or library needed for the code to work, or you've made a typo. Another possibility is that the class you'd like to refer to is in another module. If that's the case, you'll have to refer to it with its full name as in the following code.
#!/usr/bin/env ruby
module MyModule
class MyClass; end
end
c = MyModule::MyClass.new

Rails: Overriding const_missing within a module

Within my Rails application I have a module defined this way:
module WhateverModule
class WhateverClass
...
end
end
This file (whatever_class.rb) is located under /app/models/whatever_module
const_missing is being overriden by Rails and despite I did some workarounds, involving initializers, I wish I could make it in a better way.
My aim is to get a WhateverModule::Foo (Foo being undefined) to be resolved by a custom const_missing method.
Any help will be greatly appreciated. Thanks in advance!!
The following seems to work fine for me in Rails 2.2.2
module WhateverModule
def self.const_missing(c)
# handle missing constant
end
end

Resources