Rails: Logging for Code in the Lib Directory

Rails: Logging for code in the lib directory?

There's two ways to go about it:

  • Assuming your library is self-contained and has a module, you can add a logger attribute to your module and use that everywhere in your library code.

    module MyLibrary
    mattr_accessor :logger
    end

    You then either use an initializer in config/initializers/, or an config.after_initialize block in config/environment.rb to initialize your logger, like so:

    require 'mylibrary'
    MyLibrary.logger = Rails.logger

    This would still allow you to use your self-contained library from scripts outside of Rails. Which is nice, on occasion.

  • If using your library without Rails really doesn't make sense at all, then you can also just use Rails.logger directly.

In either case, you're dealing with a standard Ruby Logger. Also keep in mind that, in theory, the logger may be nil.

How to make logging in rails libs works like in models and controllers

At the end I found a better way, I just need to include Logging.globally on top of the module where I want that behavior:

# lib/custom_lib.rb
class CustomLib
include Logging.globally

def initialize
logger.info 'foo'
end
end

Set a breakpoint in lib/ directory of rails

Thanks to @Naremy, I've found my mistake. The problem was following: I've had begin...rescue block which was catching errors stopping them from floating up to output of rails server. And as the error was the same as in the other chunk of code (where I was trying to set breakpoint), I couldn't find it.
So removing rescue made a move, and now everything works as expected.

So the overall fact is: if you catch a error, neither rails server output nor better_errors gem will show you anything.

How to log something in Rails in an independent log file?

You can create a Logger object yourself from inside any model. Just pass the file name to the constructor and use the object like the usual Rails logger:

class User < ActiveRecord::Base
def my_logger
@@my_logger ||= Logger.new("#{Rails.root}/log/my.log")
end

def before_save
my_logger.info("Creating user with name #{self.name}")
end
end

Here I used a class attribute to memoize the logger. This way it won't be created for every single User object that gets created, but you aren't required to do that. Remember also that you can inject the my_logger method directly into the ActiveRecord::Base class (or into some superclass of your own if you don't like to monkey patch too much) to share the code between your app's models.

Cleanest way to make logging in Ruby Gem library be visible in Rails.logger?

You can either make sure that Rails is loaded, then fully qualify the path to the logger, (i.e. Rails.logger.warn), or make a singleton that has a property which you can set from inside your Rails application. You could then use an initializer to dependency inject the reference to your Rails logger.

Rails lib directory

One use of the lib directory (how I use it most often) is to share code between models to stay DRY. For example, if you are defining a tag_tokens attribute on many different models for use with a tokenizer input, you could put that in "tag_accessor.rb" or something, place it in /lib', and then include it with include TagAccessor. The ruby file might look like:

module TagAccessor
def tag_tokens
tags.map(&:name).join(',')
end

def tag_tokens=(names)
self.tag_ids = names.split(",").uniq
end
end

(This is an example from one of my apps, which is why it's so specific). Then to load the /lib folder in Rails 3, place this in your application.rb:

 config.autoload_paths += %W(#{config.root}/lib)

Accessing module in lib directory (Ruby on rails)

In your console/controller:

include Search
zip_code_perimeter_search(zip, radius)

In case it doesn't auto-load in Rails 3, in your config/application.rb file, you can do this:

# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += Dir["#{config.root}/lib/**/"]

Accessing models from within the lib directory in a Rails 3 project

The solution was, that my file in /lib was actually being required by a rake file, and it seems rake files are loaded before the whole auto-load system is setup by Rails, so it couldn't find the model. After I remove the require from the .rake file, everything started working.

Rails: How to test code in the lib/ directory?

In the Rails application I'm working on, I decided to just place the tests in the test\unit directory. I will also nest them by module/directory as well, for example:

lib/a.rb   => test/unit/a_test.rb
lib/b/c.rb => test/unit/b/c_test.rb

For me, this was the path of last resistance, as these tests ran without having to make any other changes.



Related Topics



Leave a reply



Submit