When Rails functions are asking for a translation (I18n.translate), I don't want to analyze their code in order to get the exact scopes etc.
How can I add a debug output into the console for every string that was asked for?
Examples:
I18n.t 'errors.messages.invalid', :scope => :active_record
# Translation for 'activerecord.errors.messages.invalid' (not) found
label(:post, :title)
# Translation for 'activerecord.attributes.post.title' not found
# Translation for 'views.labels.post.title' not found
This is not a very elegant solution, but it's worked for me. I've created an initialiser:
require 'i18n'
if (Rails.env.development? || Rails.env.test?) && ENV['DEBUG_TRANSLATION']
module I18n
class << self
def translate_with_debug(*args)
Rails.logger.debug "Translate : #{args.inspect}"
translate_without_debug(*args)
end
alias_method_chain :translate, :debug
end
end
end
You can then run commands like the following:
$ DEBUG_TRANSLATION=true rake cucumber
...and you'll see all the translations being attempted dumped to STDOUT. I don't consider this production code though, so I've kept it in a Gist, and not checked it into my main project source control at this stage.
Noddy, but it does the job.
Just a small change to put I18n debug messages in the log:
substitute this line:
puts "Translate: #{args.inspect}"
with
Rails.logger.debug "Translate : #{args.inspect}"
Related
In rails 3.2.0,is it possible to turn off rails logging for rendering of views in
ActionView:: LogSubscriber in production environment.
Currently only way i found to supress is to monkey patch it and increase the log level to debug in the below way. Is there a better way to do this or any configuration?
module ActionView
class LogSubscriber
def render_template(event)
message = "Rendered #{from_rails_root(event.payload[:identifier])}"
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
message << (" (%.1fms)" % event.duration)
debug(message)
end
alias :render_partial :render_template
alias :render_collection :render_template
end
end
ActionView uses ActiveSupport::Notifications and ActiveSupport::LogSubscriber to instrument its events, and to silence it from the logs is as simple as including the following in your environment file:
%w{render_template render_partial render_collection}.each do |event|
ActiveSupport::Notifications.unsubscribe "#{event}.action_view"
end
Cheers!
You can directly turn off action_view logger.
Rails.application.configure do
config.action_view.logger = nil
end
I'd like to find which of the tests are the slowest in my test suite based on this blog post. Here's the minified version of the code:
# test/test_time_tracking.rb
module TestTimeTracking
class ActiveSupport::TestCase
setup :mark_test_start_time
teardown :record_test_duration
def mark_test_start_time
#start_time = Time.now
end
def record_test_duration
puts "Test class: #{self.class.name}"
puts "Duration: #{Time.now - #start_time}"
end
end
end
# test/test_helper.rb
require 'test_time_tracking'
include TestTimeTracking
# ...
Is there a way to print out the test name during either the settup or teardown? In the blog post they call name attribute in the teardown block, but this throws an error in my case. I've also tried #name and #method_name with no success.
I'm using shoulda-contexts gem on top of the default Rails test framework. I know that I can get the test name and duration with rake test TESTOPTS=-v, but I will then have to run another script to parse the output.
Use minitest-reporters. Installation Guide is provided on this page.
After configration use rspec reporter. i.e in your test_helper.rb file write
Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new()]
And run the test. This 'll format output like this:
You can see the time taken by each test.
def record_test_duration
puts "Test class: #{self.class.name}"
puts "Test method: #{self.method_name}"
puts "Duration: #{Time.now - #start_time}"
end
self.method_name will print the current test method name
Rails 5
bin/rails test -v
It prints something like this:
SimpleTest#test_: Simple should be a success. = 0.26 s = .
SimpleTest#test_: Simple should be a failure. = 0.23 s = .
I ve read this nice explanation of login/nonlogin, interactive/noninteractive shells http://capistranorb.com/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/. But I found nowhere, how to run capistrano 3 in specific shell. I have tried options like:
set :pty, true # non-login, interactive but does not load .bashrc
set :default_shell, '/bin/bash --login'
set :shell, '/bin/bash --login'
but nothing helped. Thanks.
I know this is quite an old question, but the below shows how to open the SSHKit class and enable login shell, for capistrano.
# backend/sshkit.rb
module SSHKit
class CommandMap
class SuffixProvider
def initialize
#storage = CommandHash.new
end
def [](command)
#storage[command] ||= []
#storage[command]
end
def to_s(command)
self.[](command).join(" ")
end
end
def [](command)
cmd = []
if prefix[command].any?
prefixes = prefix[command].map{ |prefix| prefix.respond_to?(:call) ? prefix.call : prefix }
cmd.push(prefixes.join(" "))
end
cmd.push(#map[command])
cmd.join(" ")
end
def suffix
#suffix ||= SuffixProvider.new
end
end
class Command
def to_s
[SSHKit.config.command_map[command.to_sym], *Array(args), SSHKit.config.command_map.suffix.to_s(command.to_sym)].compact.join(' ')
end
end
end
Now you can define SSHKit command maps to enable bash --login for a specific command.
SSHKit.config.command_map[:rvm].prefix("bash --login '")
SSHKit.config.command_map[:rvm].suffix("'")
Now you can use :rvm command like below.
execute :rvm, :use, '2.2.2', '--install'
# => bash --login 'rvm use 2.2.2 --install'
I've written a blog post which explains this further. I would however recommend you use the login shell only when you must require it.
I have not found an answer for you...
But what I did was follow advice from A word about PTYs:
When Capistrano makes a connection it is a non-login, non-interactive shell. This was not an accident!
Maybe you need something that has been set in your .bash_profile as part of an interactive login? Move it to your .bashrc as that will be called by capistrano.
My webapp needs to encrypt its session data. What I setup is:
config/initializers/encryptor.rb:
require 'openssl'
require 'myapp/encryptor'
MyApp::Encryptor.config[ :random_key ] = OpenSSL::Random.random_bytes( 128 )
Session.delete_all
app/models/session.rb:
require 'attr_encrypted'
class Session < ActiveRecord::Base
attr_accessible :session_id, :data
attr_encryptor :data, :key => proc { MyApp::Encryptor.config[ :random_key ] }, :marshal => true
# Rest of model stuff
end
That all works great, and keeps the session data secured. Here's the problem: when I run my custom rake tasks it loads the initializer and clears all the sessions. Not good!
What can I put in my initializer to make sure it ONLY runs for the webapp initialization? Or, what can I put in my initializer to make it NOT run for rake tasks?
Update: OK, what I've done for the moment is add MYAPP_IN_RAKE = true unless defined? MYAPP_IN_RAKE to my .rake file. And then in my initializer I do:
unless defined?( MYAPP_IN_RAKE ) && MYAPP_IN_RAKE
# Web only initialization
end
Seems to work. But I'm open to other suggestions.
You might make a modification to your application in `config/application.rb' like this:
module MyApp
def self.rake?
!!#rake
end
def self.rake=(value)
#rake = !!value
end
Then in your Rakefile you'd add this:
MyApp.rake = true
It's nice to use methods rather than constants since sometimes you'd prefer to change or redefine them later. Plus, they don't pollute the root namespace.
Here's a sample config/initializers/rake_environment_test.rb script:
if (MyApp.rake?)
puts "In rake"
else
puts "Not in rake"
end
The programmable nature of the Rakefile affords you significant flexibility.
There is another work around:
unless ENV["RAILS_ENV"].nil? || ENV["RAILS_ENV"] == 'test'
When you launch with rake your ENV["RAILS_ENV"] will be nil. The test for 'test' is to avoid to run when using rspec.
I know that is reckon to use Rails.env but it return "development" when it is not initialised.
http://apidock.com/rails/Rails/env/class
# File railties/lib/rails.rb, line 55
def env
#_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"]
|| ENV["RACK_ENV"] || "development")
end
I wrote a little monkeypatch to the Rails MySQLAdapter and want to package it up to use it in my other projects. I am trying to write some tests for it but I am still new to testing and I am not sure how to test this. Can someone help get me started?
Here is the code I want to test:
unless RAILS_ENV == 'production'
module ActiveRecord
module ConnectionAdapters
class MysqlAdapter < AbstractAdapter
def select_with_explain(sql, name = nil)
explanation = execute_with_disable_logging('EXPLAIN ' + sql)
e = explanation.all_hashes.first
exp = e.collect{|k,v| " | #{k}: #{v} "}.join
log(exp, 'Explain')
select_without_explain(sql, name)
end
def execute_with_disable_logging(sql, name = nil) #:nodoc:
#Run a query without logging
#connection.query(sql)
rescue ActiveRecord::StatementInvalid => exception
if exception.message.split(":").first =~ /Packets out of order/
raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
else
raise
end
end
alias_method_chain :select, :explain
end
end
end
end
Thanks.
General testing
You could start reading about testing.
After you are understanding the basics of testing, you should think what you have changed. Then make some tests which test for
the original situation, resulting in errors since you updated it. So reverse the test after it indeed is working for the original situation.
the new situation to see whether you have implemented your idea correctly
The hardest part is to be sure that you covered all situations. Finally, if both parts pass then you could say that your code it working as expected.
Testing gems
In order to test gems you can run
rake test:plugins
to test all plugins of your rails application (see more in chapter 6 of the testing guide), this only works when the gem is in the vendor directory of an application.
Another possibility is to modify the Rakefile of the gem by including a testing task. For example this
desc 'Test my custom made gem.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
would run all available tests in the test directory ending with _test.rb. To execute this test you can type rake test (from the gem directory!).
In order to run the tests for the gem by default (when typing just rake) you can add/modify this line:
task :default => :test
I used the second method in my ruby-bbcode gem, so you could take a look at it to see the complete example.