Ruby - uninitialized constant - ruby-on-rails

I have this 4 classes, the code is simple but when I try to generate, it returns an error like
in `<main>': uninitialized constant PruebasUnitarias (NameError)
The code is this and I dont know what is wrong, I thought it was because of requires, but I have all in one document and still crash.
class Complejo
def initialize (real, imaginario)
#real = real
#imaginario = imaginario
end
def sumar (complejo)
#real = #real + complejo.real
#imaginario = #imaginario + complejo.imaginario
end
attr_reader :real, :imaginario
end
class Prueba
def assertCierto(valor)
return valor
end
def assertFalso(valor)
return valor
end
def assertIgual(num1, num2)
if(num1 == num2)
return true
end
return false
end
def assertDistinto(num1, num2)
if(num1 != num2)
return true
end
false
end
def assertNil param
if (param == nil)
return true
end
false
end
def assertContiene(param1, param2)
param1.include?(param2)
end
end
class PruebasUnitarias::Prueba
def run
metodos = self.methods
if(self.respond_to? :inicializacion)
self.inicializacion
end
end
end
class PruebaComplejo < PruebasUnitarias::Prueba
def inicializacion
#c1 = Complejo.new(3,5)
#c2 = Complejo.new(1,-1)
end
def prueba_suma
#c1.sumar(#c2)
assertIgual(#c1.real, 4)
assertIgual(#c1.imaginario, 4)
end
def prueba_suma_cero
#c2.sumar(Complejo.new(0,0))
assertCierto(#c2.real==1)
assertCierto(#c2.imaginario==-1)
end
def prueba_suma_nula
#c2.sumar(nil)
assertIgual(#c2.real, 1)
assertIgual(#c2.imaginario, -1)
end
def imprimir (complejo)
puts "complejo: #{complejo.real}, #{complejo.imaginario}i"
end
end

You have to declare the module before you can put a class in it. Try this instead:
module PruebasUnitarias
class Prueba
...
end
end
class PruebaComplejo < PruebasUnitarias::Prueba
...
end

Just as a note about your programming style, you need to think in simpler terms when it comes to testing your values. Consider these changes:
def assertCierto(valor)
valor
end
def assertFalso(valor)
valor
end
def assertIgual(num1, num2)
num1 == num2
end
def assertDistinto(num1, num2)
num1 != num2
end
def assertNil param
param == nil
end
It's not necessary to use an if test to see if something is equal or not equal and then return true or false. The test itself does that so simply compare the values and let Ruby return the result by default.
1 == 1 # => true
1 == 2 # => false
1 != 1 # => false
1 != 2 # => true
Also, use snake_case for method names, not camelCase. ItsAReadabilityThing:
def assert_cierto(valor)
def assert_falso(valor)
def assert_igual(num1, num2)
def assert_distinto(num1, num2)
def assert_nil param

Related

getting NoMethodError Undefined method in Ruby

getting NoMethodError Undefined method service_account_id under valid_restriction? method.
Can anybody check why am I getting this error?
If you have links to resolve this, that would be helpful too. Thanks.
Error:
ERROR:
<NoMethodError: undefined method `service_account_id' for #String:0x0000560784713130>
authentication_request.rb:19:in `valid_restriction?'
Code Snippet below:
module Authentication
module AuthnGcp
class DecodedToken
PROJECT_ID_TOKEN_CLAIM_NAME = "google/compute_engine/project_id"
INSTANCE_NAME_TOKEN_CLAIM_NAME = "google/compute_engine/instance_name"
SUB_TOKEN_CLAIM_NAME = "sub"
EMAIL_TOKEN_CLAIM_NAME = "email"
AUDIENCE_TOKEN_CLAIM_NAME = "aud"
attr_reader :project_id, :instance_name, :service_account_id, :service_account_email, :audience
def initialize(decoded_token_hash:, logger:)
#decoded_token_hash = decoded_token_hash
#logger = logger
initialize_required_claims
initialize_optional_claims
end
private
def initialize_required_claims
#audience = required_token_claim_value(AUDIENCE_TOKEN_CLAIM_NAME)
#service_account_id = required_token_claim_value(SUB_TOKEN_CLAIM_NAME)
end
def initialize_optional_claims
#service_account_email = optional_token_claim_value(EMAIL_TOKEN_CLAIM_NAME)
#project_id = optional_token_claim_value(PROJECT_ID_TOKEN_CLAIM_NAME)
#instance_name = optional_token_claim_value(INSTANCE_NAME_TOKEN_CLAIM_NAME)
end
def required_token_claim_value(required_token_claim)
required_token_claim_value = token_claim_value(required_token_claim)
if required_token_claim_value.nil? || required_token_claim_value.empty?
raise Errors::Authentication::Jwt::TokenClaimNotFoundOrEmpty, required_token_claim
end
log_claim_extracted_from_token(required_token_claim, required_token_claim_value)
required_token_claim_value
end
def optional_token_claim_value(optional_token_claim)
optional_token_claim_value = token_claim_value(optional_token_claim)
if optional_token_claim_value.nil? || optional_token_claim_value.empty?
optional_token_claim_value = nil
#logger.debug(LogMessages::Authentication::Jwt::OptionalTokenClaimNotFoundOrEmpty.new(optional_token_claim))
else
log_claim_extracted_from_token(optional_token_claim, optional_token_claim_value)
end
optional_token_claim_value
end
def token_claim_value(token_claim)
token_claim_path = token_claim.split('/')
#decoded_token_hash.dig(*token_claim_path)
end
def log_claim_extracted_from_token(token_claim, token_claim_value)
#logger.debug(
LogMessages::Authentication::Jwt::ExtractedClaimFromToken.new(
token_claim,
token_claim_value
)
)
end
end
end
end
==========================================================================
module Authentication
module AuthnGcp
# This class is responsible for retrieving the correct value from the GCP token
# of the requested attribute.
class AuthenticationRequest
def initialize(decoded_token:)
#decoded_token = decoded_token
end
def valid_restriction?(restriction)
token_value =
case restriction.name
when Restrictions::PROJECT_ID
#decoded_token.project_id
when Restrictions::INSTANCE_NAME
#decoded_token.instance_name
when Restrictions::SERVICE_ACCOUNT_ID
#decoded_token.service_account_id
when Restrictions::SERVICE_ACCOUNT_EMAIL
#decoded_token.service_account_email
end
raise Errors::Authentication::AuthnGcp::JwtTokenClaimIsMissing, restriction.name if token_value.blank?
token_value == restriction.value
end
end
end
end

How to define a class like ActiveSupport::StringInquirer

Define a class which when initialized with a string e.g. 'abc' will return true if the method 'abc?' is called on it. Any other method with a trailing '?' will return false. All other methods which doesn't have a trailing '?' will raise NoMethodError
You can use method_missing to respond to messages for which there is no method.
In method_missing we can check the method name and if it ends in a ? check if it minus the ? is equal to the string (self).
When using method_missing it is custom to also define respond_to?.
class StringInquirer < String
private
def method_missing(method_name, *args, &block)
if method_name.to_s.end_with?('?')
self == method_name.to_s.delete('?')
else
super
end
end
def respond_to?(method_name, include_private = false)
method_name.to_s.ends_with('?') || super
end
end
name = StringInquirer.new('sally')
name.sally? # => true
Note this is case sensitive.
name.Sally? # => false
class NewStrInq < String
def initialize(val)
self.class.send(:define_method, "#{val}?") do
true
end
end
def method_missing(method)
method.to_s[-1] == '?' ? false : (raise NoMethodError)
end
end
class StringInquirer < String
def initialize(str)
define_singleton_method(str + '?') { true }
super(str)
end
end
name = StringInquirer.new('sally')
name.sally? # => true
name.kim? # => NoMethodError
name.nil? # => false
By raising NoMethodError for all methods ending in a question mark you will loose nil? etc.

Having trouble with how classes work

I'm testing this code for a class assignment to make sure it works.
I don't quite understand code yet. Maybe give me some pointers.
require 'minitest/autorun'
require './human'
require './coffee'
## This assignment made more sense when I wrote it in the morning.
class CaffeineTest < MiniTest::Test
def test_humans_tend_to_be_sleepy
tyler = Human.new "Tyler"
assert tyler.alertness < 0.1
end
def test_humans_need_coffee
randy = Human.new "Randy"
refute randy.has_coffee?
assert randy.needs_coffee?
end
def test_humans_can_drink_coffee
sherri = Human.new "Sherri"
tsmf = Coffee.new "Triple Shot Mocha Frappuccino"
assert tsmf.full?
sherri.buy tsmf
sherri.drink!
assert_in_epsilon sherri.alertness, 0.33, 0.1
refute tsmf.full?
refute tsmf.empty?
end
def test_humans_can_drink_all_the_coffee
trevor = Human.new "Trevor"
tsmf = Coffee.new "Triple Shot Mocha Frappuccino"
trevor.buy tsmf
3.times { trevor.drink! }
assert tsmf.empty?
assert trevor.alertness > 0.9
end
end
Here's what I've added to it.
class Human
def initialize(name)
#name = name
#alertness = 0.0
#flavor = Coffee.new(name)
#coffee = 0
end
def alertness
#alertness
end
def has_coffee?()
false
end
def needs_coffee?()
true
end
def drink!()
#alertness += 0.33
#coffee -= 0.33
end
def empty?
if #coffee <= 0
true
else
false
end
end
def buy(type)
#flavor
#coffee += 1 #add tsmf to some kind of array or some shit
end
end
class Coffee
def initialize(drink)
#coffee = 0
end
def full?
if #coffee >= 0
true
else
false
end
end
def has_coffee?
false
end
end
I keep getting failures on empty? and full?. Please guide me a little here.
require 'minitest/autorun'
## This assignment made more sense when I wrote it in the morning.
class CaffeineTest < MiniTest::Test
def test_humans_tend_to_be_sleepy
tyler = Human.new "Tyler"
assert tyler.alertness < 0.1
end
def test_humans_need_coffee
randy = Human.new "Randy"
refute randy.has_coffee?
assert randy.needs_coffee?
end
def test_humans_can_drink_coffee
sherri = Human.new "Sherri"
tsmf = Coffee.new "Triple Shot Mocha Frappuccino"
assert tsmf.full?
sherri.buy tsmf
sherri.drink!
assert_in_epsilon sherri.alertness, 0.33, 0.1
refute sherri.empty?
end
def test_humans_can_drink_all_the_coffee
trevor = Human.new "Trevor"
tsmf = Coffee.new "Triple Shot Mocha Frappuccino"
trevor.buy tsmf
3.times { trevor.drink! }
assert tsmf.empty?
assert trevor.alertness > 0.9
end
end
class Human
def initialize(name)
#name = name
#alertness = 0.0
#flavor = Coffee.new(name)
#coffee = 0
end
def alertness
#alertness
end
def has_coffee?()
false
end
def needs_coffee?()
true
end
def drink!()
#alertness += 0.33
#coffee -= 0.33
end
def empty?
if #coffee <= 0
true
else
false
end
end
def buy(type)
#flavor
#coffee += 1 #add tsmf to some kind of array or some shit
end
end
class Coffee
def initialize(drink)
#coffee = 0
end
def full?
if #coffee >= 0
true
else
false
end
end
def has_coffee?
false
end
def empty?
if #coffee <= 0
true
else
false
end
end
end

How should i transform this concern in service object?

I have a concern allowing me to give the back end user the ability to sort elements. I use it for a few different elements. The rails community seems to be pretty vocal against concern and callbacks, i'd like to have a few pointers on how to better model the following code :
require 'active_support/concern'
module Rankable
extend ActiveSupport::Concern
included do
validates :row_order, :presence => true
scope :next_rank, lambda { |rank| where('row_order > ?',rank).order("row_order asc").limit(1)}
scope :previous_rank, lambda { |rank| where('row_order < ?',rank).order("row_order desc").limit(1)}
scope :bigger_rank, order("row_order desc").limit('1')
before_validation :assign_rank
end
def invert(target)
a = self.row_order
b = target.row_order
self.row_order = target.row_order
target.row_order = a
if self.save
if target.save
true
else
self.row_order = a
self.save
false
end
else
false
end
end
def increase_rank
return false unless self.next_rank.first && self.invert(self.next_rank.first)
end
def decrease_rank
return false unless self.previous_rank.first && self.invert(self.previous_rank.first)
end
private
def assign_default_rank
if !self.row_order
if self.class.bigger_rank.first
self.row_order = self.class.bigger_rank.first.row_order + 1
else
self.row_order=0
end
end
end
end
I think a Concern is a good choice for what you are trying to accomplish (particularly with validations and scopes because ActiveRecord does those two very well). However, if you did want to move things out of the Concern, apart from validations and scopes, here is a possibility. Just looking at the code it seems like you have a concept of rank which is represented by an integer but can become it's own object:
class Rank
def initialize(rankable)
#rankable = rankable
#klass = rankable.class
end
def number
#rankable.row_order
end
def increase
next_rank ? RankableInversionService.call(#rankable, next_rank) : false
end
def decrease
previous_rank ? RankableInversionService.call(#rankable, previous_rank) : false
end
private
def next_rank
#next_rank ||= #klass.next_rank.first
end
def previous_rank
#previous_rank ||= #klass.previous_rank.first
end
end
To extract out the #invert method we could create a RankableInversionService (referenced above):
class RankableInversionService
def self.call(rankable, other)
new(rankable, other).call
end
def initialize(rankable, other)
#rankable = rankable
#other = other
#original_rankable_rank = rankable.rank
#original_other_rank = other.rank
end
def call
#rankable.rank = #other.rank
#other.rank = #rankable.rank
if #rankable.save && #other.save
true
else
#rankable.rank = #original_rankable_rank
#other.rank = #original_other_rank
#rankable.save
#other.save
false
end
end
end
To extract out the callback you could have a RankableUpdateService which will assign the default rank prior to saving the object:
class RankableUpdateService
def self.call(rankable)
new(rankable).call
end
def initialize(rankable)
#rankable = rankable
#klass = rankable.class
end
def call
#rankable.rank = bigger_rank unless #rankable.ranked?
#rankable.save
end
private
def bigger_rank
#bigger_rank ||= #klass.bigger_rank.first.try(:rank)
end
end
Now you concern becomes:
module Rankable
extend ActiveSupport::Concern
included do
# validations
# scopes
end
def rank
#rank ||= Rank.new(self)
end
def rank=(rank)
self.row_order = rank.number; #rank = rank
end
def ranked?
rank.number.present?
end
end
I'm sure there are issues with this code if you use it as is, but you get the concept. Overall I think the only thing that might be good to do here is extracting out a Rank object, other than that it might be too much complexity that the concern encapsulates pretty nicely.

Trying to perform a method on a params in Rails

I want to write a method that loops through all the params to make sure they aren't all blank.
My params are:
params[:search][:company]
params[:search][:phone]
params[:search][:city]
params[:search][:state]
params[:search][:email]
I have this method:
def all_blank_check(params)
array=[]
params[:search].each do |key, value|
array << value unless value.blank?
end
if array.count < 1
return true
else
return false
end
end
But when I try something like all_blank_check(params) I get the following error:
NoMethodError (undefined method `all_blank_check' for #<Class:0x108c08830>):
Do I need to convert the params to an array first? Can't I perform a method on params?
Edit - full source:
def index
#customers = Customer.search_search(params)
end
def self.search_search(params)
search_field = []
search_values = []
array = []
test = ''
if !params[:search].nil? && all_blank_check(params[:search]
if !params[:search].nil? && !params[:search][:company].blank?
search_field << 'customers.company LIKE ?'
search_values << "%#{params[:search][:company]}%"
end
if !params[:search].nil? && !params[:search][:city].blank?
search_field << 'customers.city = ?'
search_values << "#{params[:search][:city]}"
end
if !params[:search].nil? && !params[:search][:phone].blank?
search_field << 'customers.phone_1 = ?'
search_values << "%#{params[:search][:phone]}%"
end
conditions = [search_field.join(' AND ')] + search_values
Customer.where(conditions).includes(:customer_contacts).limit(10)
end
end
def all_blank_check(params)
params[:search].each do |key, value|
array << value unless value.blank?
end
if array.count < 1
return false
end
if array.count > 1
return true
end
end
You can also use more Ruby-minded code like this:
def self.all_blank?(params)
params[:search].count{|key, value| !value.blank?} == 0
end
This counts the values that are not blank; if the number is 0, it means all are blank.
It avoids creating a new array just for counting.
The problem is not the type of params, the problem is that the method all_blank_check does not exist on the object you call it on.
You defined it as an instance method and you're trying to call it from the class method search_param, which won't work.
If you want to make all_blank_check a class method you need to change the definition to def self.all_blank_check(params) - same as search_param.

Resources