Ruby on Rails: configure web_console in initializer - ruby-on-rails

I am using the web_console gem and I would like to add some IPs to the whitelist. For reasons that would probably go to far to explain, can't simply add something to the config/application.rb or config/environments/development.rb. However I can create an initializer config/initializers/.
I simple tried this in config/initializers/99-webconsole.rb, but while the file is loaded (--> debug message is shown), the web console does not seem to pick up my settings.
Rails.application.configure do
config.web_console.whitelisted_ips = '10.10.0.0/16'
p "Debug: this is loaded."
end
I assume it's related to some kind of race condition? Providing the same line in config/environments/development.rb works, but as said, I sadly can not change that file.

Based on this code https://github.com/rails/web-console/blob/e3dcf4c588af526eafcf1ce9413e62d846599538/lib/web_console/railtie.rb#L59
maybe there is a code in your initializer that configuring config.web_console.permissions, so your whitelisted_ips config is ignored
whitelisted_ips is also deprecated
and have you checked that you are using v4.2.0, the permissions was buggy and fixed by this commit https://github.com/rails/web-console/commit/6336c89385b58e88b2661ea3dc42fe28651d6296

Related

What is the `domain` attribute in Rails.application.configure?

What is the domain attribute in the Rails.application.configure do block?
Currently I have,
Rails.application.configure do
config.domain = 'www.my-site.com'
end
I couldn't find an explanation from Google, and it seems like everything works the same if I remove it.
Does it have a specific purpose?
This is not a standard Rails config, it was probably set by another dev. Check for occurrences on config.domain usage on the code and you will probably understand what it does.
I'd guess it is used at least in config/environments/production.rb as the default host for e-mail.

Rails 4 custom initializer configuration variables

How can I add custom configuration variables in an initializer in Rails 4? I've tried a simple test in config/initializers/stuff.rb
Rails.application.config.stuff = 'foo'
based on the "Custom Configuration" section of this Rails Guide: http://guides.rubyonrails.org/configuring.html
I know I can add these to config/application.rb, the environments files, etc., but is there a way to make this work properly in an initializer? When I attempt to view this variable in the console, it's not there. I also do not receive any errors. Do I need a special block? Other initializers from various applications have what I have above and their configurations show up. Example from assets.rb:
Rails.application.config.assets.version = '1.0'
It appears that it does work; the problem is that pry is not autocompleting these variables, even with
Rails.application.eager_load!
set in .pryrc, and I'm not sure why that is.

Explain to me how config works in Rails

I have a Rails 3 application, call it "MyApp". In my config\environments\production.rb file I see such things as
MyApp::Application.configure do
config.log_level = :info
config.logger = Logger.new(config.paths.log.first, 'daily')
...or...
config.logger = Logger.new(Rails.root.join("log",Rails.env + ".log"),3,20*1024*1024)
So, questions are focusing on terminology and wtf they mean... (or point me to some site ,I have looked but not found, to explain how this works.)
MyApp is a module?
MyApp::Application is a ...? What, a module too?
MyApp::Application.configure is a method?
config is a variable? How do I see it in console?
config.logger is a ???
config.paths.log.first is a ...??
--in console I can see "MyApp::Application.configure.config.paths.log.first" but don't know what that means or how to extract info from it!?!
Is this too much for one question? :)
I have looked at the tutorial http://guides.rubyonrails.org/configuring.html but it jumps right into what things do.
A six sided question! Oh my. Let's ahem roll.1 Here's hoping I receive 6 times the upvotes for it then? :)
1. MyApp is a module?
Yes, it's a module. It acts as a "container" for all things pertaining to your application. For instance you could define a class like this:
module MyApp
class MyFunClass
def my_fun_method
end
end
end
Then if someone else has a MyFunClass, it won't interfere with your MyFunClass. It's just a nice way of separating out the code.
2. MyApp::Application is a ...? What, a module too?
MyApp::Application is actually a class, which inherits from Rails::Application. This does a quite a lot of things, including setting up the Rails.application object which is actually an instance of MyApp::Application that you can do all sorts of fun things on like making requests to your application (in a rails console or rails c session). This code for instance would make a dummy request to the root path of your application, returning a 3-sized Array which is just a plain Rack response:
Rails.application.call(Rack::MockRequest.env_for("/"))
You can also get the routes for your application by calling this:
Rails.application.routes
The main purpose of defining MyApp::Application is not these fun things that you'll probably never use, but rather so that you can define application-specific configuration inside config/application.rb. Things like what parameters are filtered, the time zone of the application or what directories should be autoloaded. These are all covered in the Configuration Guide for Rails.
3. MyApp::Application.configure is a method?
Indeed it is a method, and it allows you to add further configuration options to your application's configuration after config/application.rb has been loaded. You've probably seen this used in config/environments/development.rb or one of the other two files in that directory, but basically they all use the same options as shown in that Configuration Guide linked to earlier.
4. config is a variable? How do I see it in console?
The config "variable" is actually a method defined within the code used for Rails::Application and returns quite simply a configuration object which stores the configuration for the application.
To access it in the console, just use Rails.application.config. This will return quite a large Rails::Application::Configuration object for your viewing pleasure.
5. config.logger is a ???
The method you're referring to, I assume, comes from this line in config/environments/production.rb:
# Use a different logger for distributed setups
# config.logger = SyslogLogger.new
The method in this example is not config.logger, but rather config.logger=, which is referred to as a "setter" method in Ruby-land. The one without the equal sign is referred to as a "getter". This method sets up an alternative logger for the production environment in Rails, which then can be accessed by using Rails.logger within the console or the application itself.
This is useful if you want to output something to the logs, as you can simply call this code:
Rails.logger.info("DEBUG INFO GOES HERE")
6. config.paths.log.first is a ...?? --in console I can see "MyApp::Application.configure.config.paths.log.first" but don't know what that means or how to extract info from it!?!
Within a Rails application, you can modify the locations of certain directories. And so, this config.paths method is a way of keeping track of where these directories map to. In my entire Rails life I have never had to use or modify this variable and that can mean either one of two things:
It's not used often by Rails programmers, or;
I don't live a very varied life.
Interpret it as you will. My main point is that you're probably never going to use it either.
I hope these help you understand Rails a little more!
1 Terrible dice joke.
MyApp is a module, it's a namespace including an app you'll launch, see next line
MyApp::Application is a Class and you're running it's instances when running a Rails app
MyApp::Application.configure is a method. It passes all instructions to the class. See Ref.
config is a method or an instance variable (when set) which belongs through inheritance to Rails::Application::Configuration. See Ref.
You can see it in console doing: MyApp::Application.config
config.logger doesn't exist until you define it, so it's a Logger instance. See Ref.
config.paths.log is a Rails::Paths::Path
you can access it in console using: MyApp::Application.config.paths.log

What is the best way to store app specific configuration in rails?

I need to store app specific configuration in rails. But it has to be:
reachable in any file (model, view, helpers and controllers
environment specified (or not), that means each environment can overwrite the configs specified in environment.rb
I've tried to use environment.rb and put something like
USE_USER_APP = true
that worked to me but when trying to overwrite it in a specific environment it wont work because production.rb, for instance, seems to be inside the Rails:Initializer.run block.
So, anyone?
Look at Configatron: http://github.com/markbates/configatron/tree/master
I have yet to use it, but he's actively developing it now, and looks quite nice.
I was helping a friend set up the solution mentioned by Ricardo yesterday. We hacked it a bit by loading the YAML file with something similar to this (going from memory here):
require 'ostruct'
require 'yaml'
require 'erb'
#config = OpenStruct.new(YAML.load_file("#{RAILS_ROOT}/config/config.yml"))
config = OpenStruct.new(YAML.load(ERB.new(File.read("#{RAILS_ROOT}/config/config.yml")).result))
env_config = config.send(RAILS_ENV)
config.common.update(env_config) unless env_config.nil?
::AppConfig = OpenStruct.new(config.common)
This allowed him to embed Ruby code in the config, like in Rhtml:
development:
path_to_something: <%= RAILS_ROOT %>/config/something.yml
The most basic thing to do is to set a class variable from your environment.rb. I've done this for Google Analytics. Essentially I want a different key depending on which environment I'm in so development or staging don't skew the metrics.
This is how I did it.
In lib/analytics/google_analytics.rb:
module Analytics
class GoogleAnalytics
##account_id = nil
cattr_accessor :account_id
end
end
And then in environment.rb or in environments/production.rb or any of the other environment files:
Analytics::GoogleAnalytics.account_id = "xxxxxxxxx"
Then anywhere you ned to reference, say the default layout with the Google Analytics JavaScript, it you just call Analytics::GoogleAnalytics.account_id.
I found a good way here
Use environment variables. Heroku uses this. Remember that if you keep configuration in the codebase, anyone with access to the code has access to any secret configuration (aws api keys, gateway api keys, etc).
daemontool's envdir is a good tool for setting configuration, I'm pretty sure that's what Heroku uses to give application their environment variables.
I have used Rails Settings Cached.
It is very simple to use, keeps your configuration values cached and allows you to change them dynamically.

How to fix / debug 'expected x.rb to define X.rb' in Rails

I have seen this problem arise in many different circumstances and would like to get the best practices for fixing / debugging it on StackOverflow.
To use a real world example this occurred to me this morning:
expected announcement.rb to define Announcement
The class worked fine in development, testing and from a production console, but failed from in a production Mongrel. Here's the class:
class Announcement < ActiveRecord::Base
has_attachment :content_type => 'audio/mp3', :storage => :s3
end
The issue I would like addressed in the answers is not so much solving this specific problem, but how to properly debug to get Rails to give you a meaningful error as expected x.rb to define X.rb' is often a red herring...
Edit (3 great responses so far, each w/ a partial solution)
Debugging:
From Joe Van Dyk: Try accessing the model via a console on the environment / instance that is causing the error (in the case above: script/console production then type in 'Announcement'.
From Otto: Try setting a minimal plugin set via an initializer, eg: config.plugins = [ :exception_notification, :ssl_requirement, :all ] then re-enable one at a time.
Specific causes:
From Ian Terrell: if you're using attachment_fu make sure you have the correct image processor installed. attachment_fu will require it even if you aren't attaching an image.
From Otto: make sure you didn't name a model that conflicts with a built-in Rails class, eg: Request.
From Josh Lewis: make sure you don't have duplicated class or module names somewhere in your application (or Gem list).
That is a tricky one.
What generally works for me is to run "script/console production" on the production server, and type in:
Announcement
That will usually give you a better error message. But you said you already tried that?
I just ran into this error as well.
The short of it was that my rb file in my lib folder was not in a folder structure to match my module naming convention. This caused the ActiveSupport auto loader to use the wrong module to see if my class constant was defined.
Specifically I had defined the following class
module Foo
class Bar
end
end
In the root of /lib/bar.rb
This caused the autoloader to ask module Object if Bar was defined instead of module Foo.
Moving my rb file to /lib/foo/bar.rb fixed this problem.
I've encountered this before, and the AttachmentFu plugin was to blame. I believe in my case it was due to AttachmentFu expecting a different image processor than what was available, or non-supported versions were also installed. The problem was solved when I explicitly added :with => :rmagick (or similar -- I was using RMagick) to the has_attachment method call even for non-image attachments. Obviously, make sure that your production environment has all the right gems (or freeze them into your application) and supporting software (ImageMagick) installed. YMMV.
As for not getting Rails and AttachmentFu to suck up and hide the real error -- we fixed it before figuring it out completely.
Since this is still the top Google result, I thought I'd share what fixed the problem for me:
I had a module in the lib folder with the exact same name as my application. So, I had a conflict in module names, but I also had a conflict of folder names (not sure if the latter actually makes a difference though).
So, for the OP, make sure you don't have duplicated class or module names somewhere in your application (or Gem list).
For me, the cause was a circular dependency in my class definitions, and the problem only showed up using autotest in Rails. In my case, I didn't need the circular dependency, so I simply removed it.
You can try disabling all your plugins and add them back in one by one.
In environment.rb in the Initalizer section, add a line like this one:
config.plugins = [ :exception_notification, :ssl_requirement, :all ]
Start with the minimum set to run your application and add them in one by one. I usually get this error when I've defined a model that happens to map to an existing filename. For example, a Request model but Rails already has a request.rb that gets loaded first.
I had this problem for a while and in my case the error was always preceded from this S3 error:
(AWS::S3::Operation Aborted) "A
conflicting conditional operation is
currently in progress against this
resource. Please try again."
This problem usually occurs when creating the same bucket over and over again. (Source AWS Developers forum)
This was due to the fact that I had used attachment_fu to create the bucket and I had decommented the line containing the command Bucket.create(##bucket_name) in lib/technoweenie/attachment_fu/backends/s3_backends.rb (near to line 152).
Once commented or deleted the command Bucket.create(##bucket_name) the problem disappeared.
I hope this helps.
Changing class names while using STI caused this for me:
Class changed from 'EDBeneficiary' to 'EdBeneficiary'
Existing records had 'EDBeneficiary' stored in the 'type' column, so when Rails tried to load them up the exception was raised.
Fix: Run a migration to update values in the 'type' column to match the new class name.
in my case, I am getting this error in the development console but I can load the class in irb
Sorry this isn't a definitive answer, but another approach that might work in some specific circumstance:
I just ran in to this problem while debugging a site using Ruby 1.8.7 and Merb 1.0.15. It seemed that the class in question (let's call it SomeClass) was falling out of scope, but when some_class.rb file was automatically loaded, the other files it required (some_class/base.rb etc) were not loaded by the require mechanism. Possibly a bug in require?
If I required some_class file earlier, such as the end of environment.rb, it seems to prevent the object falling out of scope.
I was getting this error duo to a controller definition being in a file that wasn't named as a controller. For instance, you have a Comment model and you define the controller in a comment.rb file instead of comments_controller.rb
I had this problem with rails version 1.2.3. I could reproduce the problem only with mongrel, using console environment access didn't give any useful info. In my case, I solved making the RAILS_ROOT/html folder writable by mongrel and then restarting the web server, as some users reported here:
http://www.ruby-forum.com/topic/77708
When I upgraded rails from 1.1.6 to 1.2.6 and 2.0.5 for my app, I faced this error. In short, old plugins caused this error. These plugins were already out-dated and no update anymore (even no repo!). After I removed them, the app worked on 1.2.6 and 2.0.5. But I didn't check the detail source code of the plugins.

Resources