How to print the filename passed to `require`? - ruby-on-rails-3

When starting the Rails 3.x server (rails s), is it possible to print the path and name of each file as it is being loaded?
Something like below, but for every file that is required by Rails (think loading of each railtie, for example):
Loading boot.rb...
Loading application.rb...
Loading environment.rb...
Loading development.rb...
Loading routes.rb...
Note that I am able to do the above simply by using puts calls in the files above, but that is not what I am aiming for. Instead I would like to print the file name being required by any code, not just in my application but whenever require is called. For example, printing file names for calls to require being made inside the Rails code.
UPDATE
Thanks #ScottJShea. I used the following code:
In application.rb:
require File.expand_path('../boot', __FILE__)
module Kernel
def require_and_print(string)
puts string
require_original(string)
end
alias_method :require_original, :require
alias_method :require, :require_and_print
end
....

Looks like you would need to edit kernel.rb. Here is an SO Post about it where the responder suggests this (although you may ant to limit it to the require method):
module Kernel
def load_and_print(string)
$:.each do |p|
if File.exists? File.join(p, string)
puts File.join(p, string)
break
end
end
load_original(string)
end
alias_method :load_original, :load
alias_method :load, :load_and_print
end

Related

rails3 monkey-patch generator

I want to monkey-patch the rspec-rails generator to generates a _form.html_spec.rb template. I know how do that, but not where I should put this patch!
What I've done:
# rspec_generator_patch.rb
module Rspec
module Generators
class ScaffoldGenerator < Base
def generate_views_specs_with_form *args, &block
generate_views_specs_without_form
copy_view :_form
end
alias_method_chain :generate_views_specs, :form
end
end
end
Where I put this file? Thank you.
EDIT:
Ok, I think problem is almost solved. Instead of monkey-patch, I've inherited the specific generators and edited the method. There's the solution:
# lib/generators/rspec_modded/scaffold/scaffold_generator.rb
require 'generators/rspec/scaffold/scaffold_generator.rb'
module RspecModded
module Generators
class ScaffoldGenerator < Rspec::Generators::ScaffoldGenerator
def generate_view_specs
super
copy_view :_form
end
end
end
end
If I do rails g rspec_modded:scaffold is in list and actually work if called manually (rails g rspec_modded:scaffold test).
# config/application.rb
# ...
config.generators do |g|
g.test_framework :rspec_modded, :fixture => false, fixture_replacement: nil
g.fallbacks[:rspec_modded] = :rspec
end
For what I know, every hook_for :test_framework should call rspec_modded generator and rspec should manage the rest (fallbacks). But it doesn't work: for some reason the unit_test generator kick in! What the matter? I really don't understand...
You can put your monkey patch anywhere, as long as it gets loaded. With rails, you'd usually put it in the /lib folder.

Troubles with Rails 3 and classes in nested directories

I have a rails project that I inherited. I'm working on upgrading it from rails 2 to rails 3. I'm at 3.0.15 right now, working my way up to 3.2. In the app directory there is a support folder with classes in it. Like so:
app/
support/
sweeper.rb
grouped_list/
item.rb
list.rb
item.rb looks like this:
class Support::GroupedList::Item
attr_accessor :name, :count, :link
def initialize(name, count, link)
#name = name
#count = count
#link = link
end
end
In one of the controllers the Items class is called like this:
Support::GroupedList::Item.new name, count, link
when I try and load a page I get the error:
uninitialized constant ApplicationController::Support
My first thought was that the paths where not in the autoload so I added
config.autoload_paths += %W(#{config.root}/app/support #{config.root}/app/support/grouped_list)
in my application.rb but that didn't change anything. After looking around for examples I found that people where creating empty module in their directory structure so I created a support.rb file in the support folder that looks like this:
module Support
end
Now my error changes to
uninitialized constant Support::GroupedList
Hey! That's interesting, I don't understand why it changed but its progress right? So I add a grouped_list.rb file in the grouped_list directory. It looks like this:
module Support::GroupedList
end
But then I get
Expected ***/app/support/grouped_list/grouped_list.rb to define GroupedList
Ugh! so I change it to:
module GroupedList
end
But then I'm back to:
uninitialized constant Support::GroupedList
So clearly there is some fundamental knowledge I'm missing about loading classes in modules. This structure worked in rails 2 but breaks in rails 3.0.15. I'd really like to understand so if anyone can help me out I'd really appreciate it.
class GroupedList::Item
attr_accessor :name, :count, :link
def initialize(name, count, link)
#name = name
#count = count
#link = link
end
end
This should work. Then in your controller:
GroupedList::Item.new name, count, link
Also remember to restart your rails server/console, after you make these changes.

Rails - include module into controller, to be used in the view

I'm really new to Rails and I try to setup a module file to be used in the view. So I believe the correct behavior is to define the module as a helper within a controller and voila, it should be working. However, that's not the case for me. Here is the structure.
lib
functions
-- form_manager.rb
form_manager.rb:
Module Functions
Module FormManager
def error_message() ...
end
end
end
users_controller.rb
class UsersController < ApplicationController
helper FormManager
def new ...
Well, the structure is like the above and when I call the error_message from new.html.erb it gives me the error: uninitialized constant UsersController::FormManager.
So, first of all, I know that in rails 3 lib is not automatically loaded. Assuming that it is not mandatory to autoload the lib folder, how can I make this work and what am I missing?
BTW, please don't say that this question is duplicate. I'm telling you I've been searching for this crap for almost 2 days.
Your module is not autoloaded (at least not in 3.2.6). You have to load it explicitly. You can achieve this with the following line of code
# in application.rb
config.autoload_paths += %W(#{config.root}/lib)
You can check your autoload paths with Rails.application.config.autoload_paths. Maybe it's indeed defined for you?
Now you're sure your module gets loaded, you can check it in rails console by calling
> Functions::FormHelper
Now you can't use that module as a view helper by default. Use #included to define the helper when your module gets included. You achieve "lazy evaluation" this way. I think the problem with your code is that the helper method gets called before the module gets included. (somebody should correct me if I'm wrong)
Here's the code:
Module Functions
Module FormManager
def error_message() ...
end
def self.included m
return unless m < ActionController::Base
m.helper_method :error_message
end
end
end
You should also remove the helper line from your controller.
EDIT:
You can achieve this without autoloading. Just use require "functions/form_manager". You define a helper_method for every method. If you wish use all the module methods as helpers use
def self.included m
return unless m < ActionController::Base
m.helper_method self.instance_methods
end
EDIT2:
It appears that you don't need to use self.included. This achieves the same functionality:
class ApplicationController < ActionController::Base
include Functions::FormManager
helper_method Functions::FormManager.instance_methods
end
It appears you are namespacing FormManager inside of Functions which means you would call it by helper Functions::FormManager
Try that

How do I test a helper method in my application_helper file in Rails 3?

My application_helper.rb file:
module ApplicationHelper
def option_text(option_id)
Option.find(option_id).title
end
end
Where do I test this method at? Rails generates helper test files when I create a scaffold, but where do I put a test for this method, since it's in the Application Helper? I have tried placing the test in one of the view helper test files generated with the scaffold, but it can't find the method above.
Add a folder under test/unit called 'helpers', then create your helper test files like this:
# application_helper_test.rb
require File.dirname(__FILE__) + '/../../test_helper'
require 'action_view/test_case'
class ApplicationHelperTest < ActionView::TestCase
test 'option_text' do
assert true
end
end
There are some other helpful tips on testing helpers here:
http://technicalpickles.com/posts/helper-testing-using-actionview-testcase/

Rails 3 Engine - Provide Config For Users

I can't seem to find any documentation on how to do the following: I need to provide a config variable for any applications using my engine so that they can easily pass settings to my engine.
Does anyone have any links to a proper or accepted way to do this?
EDIT: As an update, I figured out a decent way to do this. Code is below.
# file: lib/my_engine.rb
module MyEngine
class Engine < Rails::Engine
initializer "my_engine.configure_rails_initialization" do |app|
# Engine configures Rails app here, this is not what my question was about
end
end
# This is what I was trying to figure out
def self.config(&block)
##config ||= MyEngine::Configuration.new
yield ##config if block
return ##config
end
end
This allows any application using my engine to configure it like below in any of their initializers or their environment.rb file, calling any methods defined in the MyEngine::Configuration class:
MyEngine.config do |config|
config.some_configuration_option = "Whatever"
end
Short answer:
Create a file called your_engine_class.rb and put in config/initializers of your hosting app. Here is an example of this file.
module YourEngineClass
class Engine < Rails::Engine
config.param_name = 'value'
end
end
Then inside your main engine.rb you can access:
config.param_name
Longer answer: I created a stub engine that includes this and lots of other standard configuration you'll need, you can use it as a starting point:
http://keithschacht.com/creating-a-rails-3-engine-plugin-gem/
I personally like the pattern Devise uses, which defines a class method in your engine's module and then an initializer in the parent application.
Create a class method to call from the parent application
module YourEngine
class << self
attr_accessor :your_config_var
end
def self.setup(&block)
# You can yield your own object encapsulating your configuration logic/state
yield self
end
end
Call the class method in an initializer in the parent application
YourEngine.setup do |config|
config.your_config_var = "nyan cat"
end
Now you are free to access your_config_var in your engine's initialization process. You can create a file in your engine's config/initializers directory or use the Rails Initializer hooks.
I like this approach since you have more control on what configuration object you expose to clients and aren't overriding the engine's config method.
Seems better to me as follow :
#lib/my_engine.rb
require 'rails'
module MyEngine
class Engine < Rails::Engine
end
def self.config(&block)
yield Engine.config if block
Engine.config
end
end