Implementing dry-run in ruby [duplicate] - scripting

This question already has an answer here:
Implementing dry-run in ruby script
(1 answer)
Closed 6 years ago.
anybody know how to implement dry-run option in Ruby?
I need something like this, but only for ruby.
https://serverfault.com/questions/147628/implementing-dry-run-in-bash-scripts
I've tried this, but part after else doesn't work:
DRY_RUN = true
def perform(*args)
command = args
if DRY_RUN
command.each{|x| puts x}
else
command.each {|x| x}
end
end
perform("puts 'Hello'")
Thanks for any idea in advance.
P.S I don't want use something like system("ruby -e \"puts 'Hello'\"")

On the else sentence, where you have:
command.each { |x| x }
Replace that with either system(x) if you are running a system command, or eval(x) if you are trying to run ruby code, like:
DRY_RUN = true
def perform(*args)
command = args
if DRY_RUN
command.each{ |x| puts x }
else
command.each { |x| system(x) }
end
end
or
DRY_RUN = true
def perform(*args)
command = args
if DRY_RUN
command.each{ |x| puts x }
else
command.each { |x| eval(x) }
end
end

Related

ActiveRecord: Is it possible to get the number of DB queries executed in addition to total time in the Rails log?

For every request, I get this in the logs:
Completed 200 OK in 854ms (Views: 1.0ms | ActiveRecord: 17.0ms)
Is it possible to get it to also include the number of queries?
Something like:
Completed 200 OK in 854ms (Views: 1.0ms | ActiveRecord: 17.0ms | Queries: 10)
Ideally, I'd like all the "cached" ones to show up in that count too. Ie, even if the "cache" is saving me from "N+1" queries from hitting the DB, I still want to know I have a problem.
I'm fine with monkeypatching / manually editing something, since I really want this just for my dev box.
(If this can be made civilizedly so I can have it in production, that's even better, but if not, I'm fine with just having a manually modified Rails in my own machine)
Thanks!
Daniel
I know the ThinkingSphinx gem does something quite like this, adding the time spent running Sphinx queries to the summary in the log. You can probably do something similar ( maybe by making your own gem, since I bet other people would appreciate this functionality) to make the number of queries appear.
I haven't really looked hard at how it works, but it looks like modifications to ActionController and LogSubscriber are responsible:
lib/thinking_sphinx/action_controller.rb:
module ThinkingSphinx
module ActionController
extend ActiveSupport::Concern
protected
attr_internal :query_runtime
def cleanup_view_runtime
log_subscriber = ThinkingSphinx::ActiveRecord::LogSubscriber
query_runtime_pre_render = log_subscriber.reset_runtime
runtime = super
query_runtime_post_render = log_subscriber.reset_runtime
self.query_runtime = query_runtime_pre_render + query_runtime_post_render
runtime - query_runtime_post_render
end
def append_info_to_payload(payload)
super
payload[:query_runtime] = query_runtime
end
module ClassMethods
def log_process_action(payload)
messages, query_runtime = super, payload[:query_runtime]
messages << ("Sphinx: %.1fms" % query_runtime.to_f) if query_runtime
messages
end
end
end
end
lib/thinking_sphinx/active_record/log_subscriber.rb:
require 'active_support/log_subscriber'
module ThinkingSphinx
module ActiveRecord
class LogSubscriber < ActiveSupport::LogSubscriber
def self.runtime=(value)
Thread.current['thinking_sphinx_query_runtime'] = value
end
def self.runtime
Thread.current['thinking_sphinx_query_runtime'] ||= 0
end
def self.reset_runtime
rt, self.runtime = runtime, 0
rt
end
def initialize
super
#odd_or_even = false
end
def query(event)
self.class.runtime += event.duration
return unless logger.debug?
identifier = color('Sphinx Query (%.1fms)' % event.duration, GREEN, true)
query = event.payload[:query]
query = color query, nil, true if odd?
debug " #{identifier} #{query}"
end
def message(event)
return unless logger.debug?
identifier = color 'Sphinx', GREEN, true
message = event.payload[:message]
message = color message, nil, true if odd?
debug " #{identifier} #{message}"
end
def odd?
#odd_or_even = !#odd_or_even
end
def logger
return #logger if defined? #logger
self.logger = ::ActiveRecord::Base.logger
end
def logger=(logger)
#logger = logger
end
attach_to :thinking_sphinx
end
end
end
I hope this helps.

How can I load data into database using activerecord

I have a ruby script that extracts information from a file (genbank) and I would like to load this data into the database. I have created the model and the schema and a connection script:
require 'active_record'
def establish_connection(db_location= "protein.db.sqlite3")
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => db_location,
:pool => 5,
:timeout => 5000
)
end
This is my script that outputs the data:
require 'rubygems'
require 'bio'
require 'snp_db_models'
establish_connection
snp_positions_file = File.open("snp_position.txt")
outfile = File.open("output.txt", "w")
genome_sequence = Bio::FlatFile.open(Bio::EMBL, "ref.embl").next_entry
snp_positions = Array.new
snp_positions_file.gets # header line
while line = snp_positions_file.gets
snp_details = line.chomp.split("\t")
snp_seq = snp_details[1]
snp_positions << snp_details[1].to_i
end
mean_snp_per_base = snp_positions.size/genome_sequence.sequence_length.to_f
puts "Mean snps per base: #{mean_snp_per_base}"
#outfile = File.open("/Volumes/DataRAID/Projects/GAS/fastq_files/bowtie_results/snp_annotation/genes_with_higher_snps.tsv", "w")
outfile.puts("CDS start\tCDS end\tStrand\tGene\tLocus_tag\tnote\tsnp_ID\ttranslation_seq\tProduct\tNo_of_snps_per_gene\tsnp_rate_vs_mean")
genome_sequence.features do |feature|
if feature.feature !~ /gene/i && feature.feature !~ /source/i
start_pos = feature.locations.locations.first.from
end_pos = feature.locations.locations.first.to
number_of_snps_in_gene = (snp_positions & (start_pos..end_pos).to_a).size # intersect finds number of times snp occurs within cds location
mean_snp_per_base_in_gene = number_of_snps_in_gene.to_f/(end_pos - start_pos)
outfile.print "#{start_pos}\t"
outfile.print "#{end_pos}\t"
if feature.locations.locations.first.strand == 1
outfile.print "forward\t"
else
outfile.print "reverse\t"
end
qualifiers = feature.to_hash
["gene", "locus_tag", "note", "snp_id", "translation", "product"].each do |qualifier|
if qualifiers.has_key?(qualifier) # if there is gene and product in the file
# puts "#{qualifier}: #{qualifiers[qualifier]}"
outfile.print "#{qualifiers[qualifier].join(",")}\t"
else
outfile.print " \t"
end
end
outfile.print "#{number_of_snps_in_gene}\t"
outfile.print "%.2f" % (mean_snp_per_base_in_gene/mean_snp_per_base)
outfile.puts
end
end
outfile.close
How can I load the data in outfile.txt into the database. Do I have to do something like marshall dump?
Thanks in advance
Mark
Your can write a rake task to do this. Save it in lib/tasks and give it a .rake extension.
desc "rake task to load data into db"
task :load_data_db => :environment do
...
end
Since the rails environment is loaded, you can access your Model directly as you would in any Rails model/controller. Of course, it'll connect to the database depending on the environment variable defined when you execute your rake task.
In a mere script, your models are unknown.
You have to define a minimum to use them as if in a Rails App. Simply declare them:
class Foo << ActiveRecord:Base
end
Otherwise, in a Rails context, use rake tasks which are aware of the Rails app details.

Testing for false with the Twitter Gem in rails 3

I'm using the Twitter gem, and I want to take a list of users from my Friend model and test to see if they're being following a Twitter user, then ... unfollow if the Twitter API returns false. Trouble is, it seems the code I'm using below never evaluates as false, even when the API returns false so it's always reverting to the else section.
I've tried variations like if ret == 'false' and it's not worked.
ret = #t.friendship?(#id_str, f.screen_name)
if ret == false
#t.unfollow(f.screen_name)
puts "#{f.screen_name} has been unfollowed."
self.update_unfollowed_column(f.id, false)
else
self.update_following_column(f.id)
end
In the console, though, if I do:
r = t.friendship?('user1', 'user2')
=> false
And then, I can do:
r == false
=> true
So, I'm not sure exactly what I'm doing wrong with the code in my Friend model.
Before the if statement, try debugging what the result is from the friendship? method:
logger.info ret.class.name # => FalseClass if it's actually false,
# => String if it's 'false'
logger.info ret.inspect # => "false" if it's false.
logger.info((ret == false).inspect) # => Should be "true"

Check what command was used inside a custom Rails 3 generator

How can you tell if a generate or destroy command has been used to invoke a custom generator?
In Rails 2 you could do this:
if options[:command] == :destroy
...
end
I want to print out some helpful information, but only when rails generate has been called, not when rails destroy is called:
if is_generating
puts "You're generated something!"
end
Thanks.
check the generator class's behavior. It seems you should get either :invoke for generate or :revoke for destroy. For example, I added this:
class PatternGenerator < Rails::Generators::NamedBase
def echo_behavior
p "generate? #{generating?}"
p "destroying? #{destroying?}"
end
protected
def generating?
:invoke == behavior
end
def destroying?
:revoke == behavior
end
end
Running this, I get:
younker % rails g pattern foo
"generate? true"
"destroying? false"
younker % rails destroy pattern foo
"generate? false"
"destroying? true"
Seems to work and makes sense, so that's my final answer.

Is there an existing I18N translation for booleans?

I need to display "Yes" or "No" in various languages based on whether a expression is true or false. Currently I am doing it like this:
fr.yml:
fr:
"yes": Oui
"no": Non
a helper method:
def t_boolean(expression)
(expression) ? t("yes") : t("no")
end
erb:
Valid: <%= t_boolean(something.is_valid?) %>
Is there some better way to do this?
Does Rails already have translations for true/false like this?
After reading this, I got inspired and figured out this solution:
fr.yml
fr:
"true": Oui
"false": Non
erb:
Valid: <%= t something.is_valid?.to_s %>
Update
For english, if you want to use yes and no as values, be sure to quote them:
en.yml
en:
"true": "yes"
"false": "no"
Just as Zabba says works fine, but if you are trying to translate true-false into yes-no, quote both sides, else you'll get true translated into true (TrueClass) again.
en:
"true": "yes"
"false": "no"
You may try overriding I18n's default translate method, delegating to the default method to do the actual translation. Use this code in an initializer:
module I18n
class << self
alias :__translate :translate # move the current self.translate() to self.__translate()
def translate(key, options = {})
if key.class == TrueClass || key.class == FalseClass
return key ? self.__translate("yes", options) : self.__translate("no", options)
else
return self.__translate(key, options)
end
end
end
end
# Inside initializer
module I18n
class << self
alias :__translate :translate # move the current self.translate() to self.__translate()
alias :t :translate
def translate(key, options = {})
if key.class == TrueClass || key.class == FalseClass
return key ? self.__translate("boolean.true", options) : self.__translate("boolean.false", options)
else
return self.__translate(key, options)
end
end
end
end
# Inside locale
boolean:
:true: 'Yes'
:false: 'No'
# Calling translate
I18n.translate(is_this_my_boolean_column)
Working with Rails 3.2.2 :)
Remember that the translate method had been aliased in I18n.
When you alias a method you are actually creating a new copy of it so only redefining the translate method will not work when calls to the t method occurs.
In order to make the above code to work you could, for example, alias the t method, too.
module I18n
class << self
alias :__translate :translate # move the current self.translate() to self.__translate()
alias :t : translate # move the current self.t() to self.translate()
def translate(key, options = {})
if key.class == TrueClass || key.class == FalseClass
return key ? self.__translate("yes", options) : self.__translate("no", options)
else
return self.__translate(key, options)
end
end
end
end
Other solution I prefer:
# Create a helper
def yes_no(bool_value)
if bool_value
t(:yes_word)
else
t(:no_word)
end
end
# Add the translations, important that you use " around yes or no.
yes_word: "No"
no_word: "Yes"
# In your views, in my case in slim:
span= yes_no myvalue
# Or ERB
<%= yes_no(myvalue) %>
For any boolean translation
I just love that boolean pluralization hack
# some_view.html.erb
t(:are_you_ok?, count: (user.is_ok? ? 0 : 1) ).html_safe
Translations
# locales/en.yml
en:
are_you_ok?:
zero: "You are <strong>NOT</strong> ok ! Do something !"
one: "You are doing fine"
You don't even need quotes actually ^^.