Rails uninitialized constant in initializers - ruby

I've taken over a working Rails 3 app from an offshore supplier and rails console is failing at this line:
Settings.defaults[:processing_fee] = '0.99'
in the file config/initializers/settings.rb
I've compared this file with what is in git blame and it matches. I've removed the contents of this file and it runs so it doesn't like this line. Reading on SO I've made the filename and constant Singular. Following another SO post I created another file in config/application_settings.rb. The constant could not be found in console. Moving it to /initializers yielded on rails console
/Users/sam/apps/tickat/config/initializers/application_settings.rb:1:in `<top (required)>': uninitialized constant SETTINGS (NameError)
from this content:
SETTINGS[:processing_fee] = '0.99'
It appears that something about my environment is not accepting my constants here. I first noticed this pushing to Heroku and can replicate this error in development in console. I've asked around and am stuck. I'm sure it's something I goofed on, sam

It might be that someone forgot to commit a file in the repo of your application.
If this is the case, and you can't get the file from the author, you need to reverse engineer Settings. I would make it an empty module:
module Settings
def self.defaults
#defaults ||= {}
end
end
And see how far you can get, before you get more errors...
EDIT: You can see in the console how this Hash is initalized:
irb(main):008:0> Settings.defaults
=> {}
irb(main):010:0> Settings.defaults[:a] = 1
=> 1
irb(main):011:0> Settings.defaults
=> {:a=>1}

Related

How to read values from _config.yml file in Jekyll hook

I am trying to read specific part of _config.yml in my Jekyll hook method something like this:
Jekyll::Hooks.register :site, :after_init do
lm = Jekyll.config("latex-macros")
end
in _config.yml is:
latex-macros:
- ["\\RR", "\\mathbb{R}"]
so in lm variable should be:
[["\\RR", "\\mathbb{R}"]]
I already tried to to use Jekyll.configuration({})["latex-macros"] and it kinda worked but it ignores --config terminal option and reads file everytime it is called. This makes it unusable for me.
I also tried
Jekyll::Hooks.register :site, :after_init do
lm = context.registers[:site].config["latex-macros"]
end
but it throws run time error:
katex.rb:8:in '<top (required)>': undefined local variable or method 'context' for main:Object (NameError)
My question is, how to read _config.yml values in jekyll hook properly? How do I fix second method?
Thank you for your help
I am writing this from top of my head since it's been a long time I used Jekyll. You need to pass site variable into hook.
Jekyll::Hooks.register :site, :after_init do |site|
# Access using site.config[key]
puts site.config['latex-macros']
end

Unable to autoload constant controller (in production). No error in development

File name -
app/controllers/invoice/inventory/department/pharmacy_invoices_controller.rb
File content -
class Invoice::Inventory::Department::PharmacyInvoicesController < ApplicationController
...
end
I get no error in development but in production I get this error -
F, [2016-04-25T13:08:00.754597 #13500] FATAL -- :
LoadError (Unable to autoload constant Invoice::Inventory::Department::PharmacyInvoicesController, expected /xxxxxx/yyyyyyy/app/controllers/invoice/inventory/department/pharmacy_invoices_controller.rb to define it):
I did ssh and checked every file on server. Its the same as development, which is obvious. I can't figure out why its throwing such an error in production.
This is covered in the rails docs, specifically in Autoloading and Reloading Constants and Nesting.
This is because defining nesting can be done in 2 ways and are very different in terms of how its seen by rails. You can check this by using Module.nesting:
module Foo
class Bar
Module.nesting
end
end
=> [Foo::Bar, Foo]
class Foo::Bar
Module.nesting
end
=> [Foo::Bar]
If you want to know more I recommend this really good blog post by Simon Coffey: Rails Autoloading Hell

How to parse and dump Ruby config files?

In this blog post he gives this example of a Ruby config file.
config do
allow ['server.com', `hostname`.strip]
vhost 'api.server.com' do
path ‘/usr/local/api’
end
vhost 'www.server.com' do
path '/usr/local/web'
end
%w{wiki blog support}.each do |host|
vhost "#{host}.server.com" do
path "/usr/local/#{host}"
end
end
end
I think of a hash after a config file have been loaded, but maybe that is not how this type of configs are intended for...
Update
If I execute it, I get
$ ruby config.rb
config.rb:2:in `<main>': undefined method `config' for main:Object (NoMethodError)
Question
What Ruby code is needed to parse and dump the content of this config file?
That config example is not directly loadable and, if I understand the blog post author correctly, it's not meant to be either so there's no easy way of loading/parsing that example.
The key part is in the blog post where he states "build simple DSLs to design semantically robust config files without the underlying ruby being conspicuous" (my emphasis). The 'underlying ruby' I take to mean the code that enables the DSL elements you're seeing such as 'config' and 'vhost'.
Your original question was, however, what code is required to load that config - below is a sample of something would work, full implementation is up to you and tbh I'm pretty sure there are cleaner, "better" ways of doing the same.
class AppConfig
attr_accessor :hosts
def allow(hosts)
#hosts = hosts
end
def vhost(hostname)
end
def process_config(&block)
instance_eval(&block)
end
end
def config(&block)
config = AppConfig.new
config.process_config &block
puts "Hosts are: #{config.hosts}"
end
load 'config.rb'

Padrino Tutorial: Can't Modify Frozen String (Runtime Error)

I am following the Padrino tutorial from here:
https://www.padrinorb.com/guides/blog-tutorial
I am copy and pasting the commands but I quickly ran into an error I don't understand:
$ padrino g controller posts get:index get:show
create app/controllers/posts.rb
create app/views/posts
apply tests/shoulda
/Users/waprin/.rvm/gems/ruby-2.1.0/gems/padrino-gen-0.12.4/lib/padrino-gen/generators/controller.rb:66:in `prepend': can't modify frozen String (RuntimeError)
from /Users/waprin/.rvm/gems/ruby-2.1.0/gems/padrino-gen-0.12.4/lib/padrino-gen/generators/controller.rb:66:in `create_controller'
This might be a bit late, but in case anyone else runs across this error (and because I just worked through the same tutorial) I'll post anyway...
It looks like there's an issue when generating controllers if a test component is specified. In this case you're using shoulda, but the same happens when using rspec and maybe others. It's been reported as a bug: https://github.com/padrino/padrino-framework/issues/1850 and has been fixed, but isn't yet part of a stable release.
One option to fix this would be to change your Gemfile to work with the latest from their github repo. To do this delete your GemFile.lock file, and comment out the line under 'Padrino Stable Gem' in your GemFile:
gem 'padrino', '0.12.4'
then uncomment the line under 'Or Padrino Edge':
gem 'padrino', :github => 'padrino/padrino-framework'
then re-run bundle install.
Of course, you'll no longer be running the stable release, and that may come with other trade-offs.
As a side-note, I believe that the guide on that page is fairly out of date. I also needed to replace:
get :index do
#posts = Post.all(:order => 'created_at desc')
render 'posts/index'
end
with:
get :index, :provides => [:html, :rss, :atom] do
#posts = Post.order('created_at desc')
render 'posts/index'
end
in the Post controller as the active record interface has changed since the time that the guide was written.
I was able to sole this problem by simply going to padrino gem path.
For me it was:
/Users/ahmadhassan/.rvm/gems/ruby-2.2.0/gems/padrino-gen-0.12.4/lib/padrino-gen/generators
open controller.rb and change line number 61:
path = #controller
to
path = #controller.dup

Call one Ruby Script from Another

I am having a perplexing problem. I want to call one ruby script from another.
With this in mind, I create a testscript.rb and executed it, it contains this code,
require './paypal.rb'
puts paypal['L_AMT0']
This code returns a number, which is my paypal balance. It relies on a paypal.rb file which uses the ruby-paypal gem. When I do ruby testscript.rb I get the output of my paypal balance, which means it is working properly. This tells me that my method for calling one RB from another is okay, since, in the above scenario, testscript.rb is getting a variable that is returned from paypal.rb.
Using this same logic, I inserted the above code into another program which is called SiriProxy. It is a ruby program. I need it to get my paypal balance.
So Inside that program, I did a require paypal.rb, it failed because it could not find it, so I set an absolute path in require which fixed it.
However, when SiriProxy (the other ruby rb giving me an issue) trys to run puts paypal['L_AMT0'] it results in an error and ends the program.
This is the error,
[Info - Plugin Manager] Say: Checking Paypal Balance
/home/siriproxy/.rvm/gems/ruby-1.9.3-p194#SiriProxy/gems/siriproxy-0.3.0/plugins/siriproxy-example/lib/siriproxy-example.rb:47:in `block in <class:Example>': undefined local variable or method `paypal' for #<SiriProxy::Plugin::Example:0x931a228> (NameError)
from /home/siriproxy/.rvm/gems/ruby-1.9.3-p194#SiriProxy/bundler/gems/cora-1edcfb9073d5/lib/cora/plugin.rb:47:in `instance_exec'
from /home/siriproxy/.rvm/gems/ruby-1.9.3-p194#SiriProxy/bundler/gems/cora-1edcfb9073d5/lib/cora/plugin.rb:47:in `block (2 levels) in process'
In the above output it appears the issue is it does not understand "paypal", as seen here:
undefined local variable or method `paypal'
However, I do not understand why, since in testscript.rb I do the exact same thing and it works.
Can anyone help? Thank you.
Seems like #CodeGnome is right.
From the Kernel documentation:
require(name) → true or false
Loads the given name, returning true if successful and false if the
feature is already loaded.
require_relative(string) → true or false
Ruby tries to load the library named string relative to the requiring
file’s path. If the file’s path cannot be determined a LoadError is
raised. If a file is loaded true is returned and false otherwise.
Loading Files from the Current Directory
I don't know anything about your library or its internals, but it looks like your require statement may be wrong. If you want to load a file from the current directory in Ruby 1.9.3, you should use:
require_relative 'paypal'
Bundler and Gems
If it's a gem that you've installed as part of a bundle (e.g. the gem is defined in a Gemfile), then providing a path in your require statement is wrong. Instead, you need to require the bundled gem as follows:
require 'bundler/setup'
require 'paypal'

Resources