Discover what i18n keys are looked up - ruby-on-rails-3

I'm using Formtastic to display a form, but it is not looking up the label value I expect.
It's defined in the yaml file as:
en:
activerecord:
attributes:
my_model:
foo:
and it used to work in rails 2.3 but is now failing after upgrading the app to rails 3.2 and newer formtastic. I can only guess that it is looking for something else.
Is there a way to log every call to translate to see what is being looked up?

Solved. Formtastic was configured with:
Formtastic::FormBuilder.label_str_method = :titleize
which bypassed the humanize method that actually looks up I18n data.

Related

Use Ruby Extension (.bundle) in Rails Applications

I have a built a Ruby Extension for C/Objective-C and now would like to use it in a Ruby on Rails web application but everytime I try to require it, WEBrick crashes! What I have is:
I have a Ruby Class: MyRubyObject which is tied to a C class (MyExtension).
MyRubyObject has been defined with one method: myRubyMethod which is tied to a function in my C class, MyExtension: myextensionmethod which just returns a string.
myextensionmethod essentailly calls another library which performs a load of work (multiple threads and what not) but finally returns a string
after compiling everything I get a MyRubyObject.bundle file. Using IRB, I can:
require './MyRubyObject'
p = MyRubyObject.new
p.myRubyMethod
=> "Result!"
This all works absolutely fine and now I want to use it in a RoR app
I put the MyRubyObject.bundle in lib in my RoR app and then from a controller class I do a require ./lib/MyRubyObject.bundle and WEBrick crashes!!!!
Any help would be greatly appreciated!!!
Cheers
I found a solution where from here: ruby-ldap gem not work in rails3 app, but work in rails console whereby I
Put a 'require File.expand_path('../../lib/MyRubyObject', __FILE__)' in config/environment.rb file (after 'require File.expand_path('../application', __FILE__)')
Then in my controller file I just put a require 'MyRubyObject' and was then able to instantiate normally: p = MyRubyObject.new ...
So I presume this was a related issue to WEBrick loading things in an incorrect order based upon the above link but I will keep an eye on this as we'll move servers most likely and this issue may pop it's ugly head up again!
Hope this helps others!
Thanks

How can I run a Controller Action from Rails Console, but setting the request.shot?

I'm working on a multi-tenant application, so pretty much everything throughout (starting with routing) expects to have a "request.host" that looks like "tenant_id.myapp.com".
I'm trying to run a controller action from the Rails console, but I haven't been able to figure this one out.
The easiest thing to do seems to be "app.get", but I can't figure out how to set the host.
I also saw an answer that mentions using "ActionController::TestProcess", which as far as I understand has been removed from Rails (or if not, I haven't found how to include it)
Any other options?
Thanks!
Daniel
I just verified it in my console(Pry)
# Send request with fake HTTP_HOST
>>app.get(app.root_path, nil, {"HTTP_HOST" => "123.myapp.com"})
>>#=>200
# Then check if it works
>>app.request.env
>>#...
>># "HTTP_HOST" : "123.myapp.com"

logging info with rails

Moving over from django / python, I am having a little trouble getting the rails logger to log all the information I want. I am wondering how/if the following can be achieved:
Having in the log format(ter) include the specific file, function name and line where the logging statement itself was found. Essentially the equivalent of LOG_MSG_FORMAT = '%(asctime)s %(levelname)s %(filename)s:%(funcName)s(%(lineno)d) : %(message)s' in python logger?
Being able to log all requests, via something similar to a django request logging middleware. Particularly, being able to log the username (if logged in) of every request.
Am I missing something obvious? or does this require (lots of) custom code?
I just found this railtie gem that might help although I imagine it will take some "custom code" to append username to logs. See the Readme section on logging specific controllers and models.
logging-rails railtie
I don't know about getting the file, function, and line number, but it's pretty easy to log from application_controller:
class ApplicationController < ActionController::Base
before_filter :log_user
def log_user
if current_user
Rails.logger.info "Processing Request for #{current_user.name}"
end
end
end
Just to add a quick note in case this is useful for someone:
The lograge gem makes rails logs much similar to django's, plus allows very neat customization, adding parameters such as remote ip address, current_user etc.
It also reduces verbosity of rendered layouts, which I anyway found unnecessary for production. It also plays nicely with logging-rails railtie mentioned by #lukewendling.
Sadly, I still couldn't find anything that shows the file/function/line number like you can easily do with django, but I guess that's just too much to ask.

How can _know_ which JSON renderer is active in my Rails 3 app?

This is a direct follow-on to this question: What is the fastest way to render json in rails?
My app does a database query and render to JSON for a JS callback. It takes at least 8 seconds for a small (1 MB) dataset, and more like 20 for a large (3.5 MB) one. This is basically going to kill my app as an idea. My users aren't going to put up with this sort of wait.
I've read about multi_json and oj and yajl, and I think I've got them installed, but none of the ways I've tried to activate the various gems in my Gemfile show any improvement in serializing time. How can I prove that I'm using one over the other, so that I compare results between them? I can't find any way of outputting (to the Rails debug log or the JS console in the browser) which library might have gotten used for the actual 'render :json => #data' call.
Instead of fiddling with your controller, a better way is to use the Rails console, like so:
$ rails console
Loading development environment (Rails 3.2.8)
1.8.7 :001 > MultiJson.engine
=> MultiJson::Adapters::JsonGem
You can interact directly with your Rails stack that way.
I finally figured out I could do 'render :text => MultiJson.engine' in my controller. This yielded "MultiJson::Engines::Oj".
It confirms that I'm already using the supposedly fastest JSON library, and I may be hosed. I guess I'll try to return pure text through the controller (which takes 2 seconds compared to 8) and see how fast a routine to convert that to a hash will take...

Raising route not found error

I'm writing a book on Rails 3 at the moment and past-me has written in Chapter 3 or so that when a specific feature is run that a routing error is generated. Now, it's unlike me to go writing things that aren't true, so I'm pretty sure this happened once in the past.
I haven't yet been able to duplicate the scenario myself, but I'm pretty confident it's one of the forgotten settings in the environment file.
To duplicate this issue:
Generate a new rails project
important: Remove the public/index.html file
Add cucumber-rails and capybara to the "test" group in your Gemfile
run bundle install
run rails g cucumber:skeleton
Generate a new feature, call it features/creating_projects.feature
Inside this feature put:
This:
Feature: Creating projects
In order to value
As a role
I want feature
Scenario: title
Given I am on the homepage
When you run this feature using bundle exec cucumber features/creating_projects.feature it should fail with a "No route matches /" error, because you didn't define the root route. However, what I and others are seeing is that it doesn't.
Now I've set a setting in test.rb that will get this exception page to show, but I would rather Rails did a hard-raise of the exception so that it showed up in Cucumber as a failing step, like I'm pretty sure it used to, rather than a passing step.
Does anybody know what could have changed since May-ish of last year for Rails to not do this? I'm pretty confident it's some setting in config/environments/test.rb, but for the life of me I cannot figure it out.
After I investigate the Rails source code, it seems like the ActionDispatch::ShowExceptions middleware that responsible of raising exception ActionController::RoutingError is missing in the test environment. Confirmed by running rake middleware and rake middleware RAILS_ENV=test.
You can see that in https://github.com/josh/rack-mount/blob/master/lib/rack/mount/route_set.rb#L152 it's returning X-Cascade => 'pass' header, and it's ActionDispatch::ShowExceptions's responsibility to pick it up (in https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L52)
So the reason you're seeing that your test case is passing because rack-mount is returning "Not Found" text, with status 404.
I'll git blame people and get it fix for you. It's this conditional here: https://github.com/rails/rails/blob/master/railties/lib/rails/application.rb#L159. If the setting is true, the error got translated right but we got error page output. If it's false, then this middleware doesn't get loaded at all. Hold on ...
Update: To clearify the previous block, you're hitting the dead end here. If you're setting action_dispatch.show_exceptions to false, you'll not get that middleware loaded, resulted in the 404 error from rack-mount got rendered. Whereas if you're setting action_dispatch.show_exceptions to true, that middleware will got loaded but it will rescue the error and render a nice "exception" page for you.