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
endYou then either use an initializer in
config/initializers/
, or anconfig.after_initialize
block inconfig/environment.rb
to initialize your logger, like so:require 'mylibrary'
MyLibrary.logger = Rails.loggerThis 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
Can't Use Compass After Installing It
Convert Datetime String to Utc in Rails
How to Get an Array with Column Names of a Table
How to Force Ruby to Show a Full Stack Trace
How to Read the Body Text of an Email Using Ruby's Net/Imap Library
How to Make Object Instance a Hash Key in Ruby
How to Use Active Record Without Rails
How to Install Gems with Apt-Get on Ubuntu
How to Export a Ruby Array from My Heroku Console into CSV
How to Add a Method to the Global Scope in Ruby
Disable Rvm or Use Ruby Which Was Installed Without Rvm
Rails: Logging for Code in the Lib Directory
Listing the Names of Associated Models
How to Uninstall Ruby on Rails and Do a Clean Install
Ruby Class with Static Method Calling a Private Method
What Are the Uppercase and Lowercase Rules of Ruby Method Name