Implement array and iterate - ruby

I have this Ruby code that I want to use:
if args[:remove_existing_trxs] == 'true'
Acquirer.delete_all
Company.delete_all
Currency.delete_all
AdminUser.delete_all
BaseReseller.delete_all
Terminal.delete_all
Contract.delete_all
Merchant.delete_all
MerchantUser.delete_all
PaymentTransaction.delete_all
end
How can I define it as an array and iterate?

Something like that?
[Model1, Model2].each do |model|
model.public_send(:delete_all)
end
Or with using Symbol#to_proc:
[Model1, Model2].each(&:delete_all)

try this out:
if args[:remove_existing_trxs] == 'true'
[Acquirer, Company, Currency, AdminUser,
BaseReseller, Terminal, Contract, Merchant,
MerchantUser, PaymentTransaction].each(&:destroy_all)
end

Related

Is multiple include?() arguments in ruby possible?

def coffee_drink?(drink_list)
drink_list.include?("coffee") ? true : drink_list.include?("espresso") ? true : false
end
I am learning Ruby with TOP and am looking to check for more than a single argument with the include function. I don't think my solution is too bad but surely there is a better solution I am just unable to find.
e.g. include?("ABC", "CBA) and include?("ABC" || "CBA") wont work.
def coffee_drink?(drink_list)
%w(coffee espresso).any? { |drink| drink_list.include?(drink) }
end
or
def coffee_drink?(drink_list)
(%w(coffee espresso) & drink_list).any?
end
note that your version could be rewritten like this
def coffee_drink?(drink_list)
drink_list.include?("coffee") || drink_list.include?("espresso")
end

Select a record based on translated name

on ruby console when I do Resource.all it give me the following:
[<Resource id:'...', name_translated:{"en"=>'vehicle',"fr"=>'véhicule'}> ...]
How do I make a selection such that Resource.find_by_name_translated("vehicle")
This would work, I think it's not the most efficient way though:
#app/models/resource.rb
def self.find_by_english_name(name)
Resource.all.select do |resource|
resource.name_translated['en'] == name
end
end
if you want to be able to find by multiple languages (defaulting to english) with one method, try this:
def self.find_by_name(name, language = 'en')
Resource.all.select do |resource|
resource.name_translated[language] == name
end
end
Since you're using Postgres this can also be written as follows:
def self.find_by_name(name, language = 'en')
Resource.where("name_translated ->> '#{language}' = '#{name}'")
end
I'd use regex query if your db doesn't allow to query by json fields:
Resource.where("name_translated LIKE '#{translated_name}%'")

pass class as parameter in Ruby

My current sinatra router looks like this but multiple stores are on the way so i would like to replace this case with one line,
get_or_post "/list.json" do
case
when params[:store]=='storeVakanties' then return jsonp(get_data_for(Vakantie))
when params[:store]=='storeDeelnemers' then return jsonp(get_data_for(Deelnemer))
when params[:store]=='storeJobstudenten' then return jsonp(get_data_for(Jobstudent))
end
end
if i rename my ExtJs store to the name of the activerecord class i could do something like
get_or_post "/list.json" do
jsonp(get_data_for(params[:store])) #eg params[:store]='Vakantie'
end
but i need to pass a class, not a string.. any suggestions ?
In the simplest case (no namespaces) you can use:
Object.const_get(params[:store])
If you need to get namespaced constant, you can do
params[:store].split('::').inject(Object) {|klass, name| klass.const_get(name) }
For more advanced implementation have a look at the source of constantize method from ActiveSupport's Inflector: http://apidock.com/rails/v4.0.2/ActiveSupport/Inflector/constantize
If you want to restrict the available classes, something like this would work:
params = { store: "Vakantie" }
[Vakantie, Deelnemer, Jobstudent].find { |c| c.to_s == params[:store] }
#=> Vakantie
I would probably just write a helper method and map the classes explicitly:
helpers do
def store(name)
case name
when 'storeVakanties' then Vakantie
when 'storeDeelnemers' then Deelnemer
when 'storeJobstudenten' then Jobstudent
end
end
end
get_or_post "/list.json" do
jsonp(get_data_for(store(params[:store])))
end
You could use eval:
get_or_post "/list.json" do
jsonp(get_data_for(eval(params[:store])))
end
If you’re horrified by that, you could use const_get:
Kernel.const_get(params[:store])
You’ll need to perform some validation, though, because it’s dangerous to allow user input to select any defined class.
I found a solution myself using ActiveSupport's constantize
jsonp(get_data_for(params[:store].constantize))
In my case security isn't an issue but i like the solution from Stefan the best so i give him the credits.

Simplifying an "any of" check with or-operator in Ruby

How to simplify the following check ?...
if node[:base][:database][:adapter].empty? || node[:base][:database][:host].empty? ||
node[:base][:database][:database].empty? || node[:base][:database][:port].empty?
to something like
required_keys = { :adapter, :host, :database...etc...}
required keys - node[:base][:database] == []
This syntax is a little off, but basically subtract the keys you have from the set of required keys. If you have all the required keys in your set, the result should be empty.
I am not sure regarding the correct syntax ? . Any help would be appreciated
required_keys = [:adapter, :host, :database ]
if required_keys.any?{|x| node[:base][:database][x].empty?}
#code here
end
Or you could do also:
node[:base][:database].values_at(*required_keys).any?(&:empty?)
If you think you're going to use this functionality multiple places, you can extend the Hash class and require the extension in an initializer.
class Hash
def contains_values_for?(*keys)
keys.all? do |key|
self[key].present?
end
end
end
Now you can do:
node[:base][:database].contains_values_for?(:adapter, :host, :database, :port)

How to list the description of all Revision within a Task?

Trying to print out Description of all Revisions within a task for a given set of tasks. But RevisionHistory seems to be a HashArray and not a RallyObject. Not sure how to proceed. Any help here would be appreciated. Here is a snippet of the direction I am taking. What should I replace the ------ with?
results.each do |task|
#revisions = task.rally_object['RevisionHistory'].-------
#revisions.each do |task_revision|
puts task_revision["Description"]
end
end
you shouldn't need to get at the RallyObject there, instead that class was meant to have convenience methods via method missing or [FieldName] to get at the fields for each object. For example try your loop as:
results.each do |task|
#revisions = task['RevisionHistory']['Revisions']
#you may need a #revisions = task['RevisionHistory'].read or something like that depending what you fetched in your query.
#revisions.each do |task_revision|
puts task_revision["Description"]
end
end
Hope that helps.

Resources