I have controller as follows
def city
params.require(:id)
begin
#data = #user.city_details(Integer(params[:id]),
params[:flag]
rescue ArgumentError => e
render_error(:bad_request, e.message)
end
end
model.rb
def city_details(id, flag = 'N')
StoredProcedure::User::GetCityDetails.exec!(
id,
flag
)
end
end
so you can see in model i have flag value default 'N'. How do i update controller so that if flag value is passed as true then update it to Y and if passed false then update it to N?
flag = params[:flag] == '1' ? 'Y' : 'N'
#data = #user.city_details(params[:id].to_i, flag)
I assume that you have some sort of checkbox that will return '1' for true and '0' for false (usual case in rails). If not, alter params[:flag] == '1' condition to your needs.
Related
I am struggling to understand how I can access an array with a hash key. In my code, I create a hash with keys and values. Now, I want to set the values in a Car class. Whenever I try to instantiate the Car, the argument expects Integer and not a String.
I am getting the following error: TypeError (no implicit conversion of String into Integer)
Here is my code:
class Car_maker
attr_accessor :car_maker
def initialize(car_maker)
#car_maker = car_maker
end
end
class Car_model < Car_maker
attr_accessor :km, :type, :transmission, :stock, :drivetrain, :status,
:fuel, :car_maker, :model, :year, :trim, :features
#total number of instances & array with car objects
##totalCars = 0
##catalogue = []
def initialize(km, type, transmission, stock, drivetrain, status, fuel, car_maker, model, year, trim, features)
super(car_maker)
#km = km
#type = type
#transmission = transmission
#stock = stock
#drivetrain = drivetrain
#status = status
#fuel = fuel
#model = model
#year = year
#trim = trim
#features = features
##totalCars += 1
end
def self.convertListings2Catalogue(line)
#Initialise arrays and use them to compare
type = ["Sedan", "coupe", "hatchback", "station", "SUV"]
transmission = ["auto", "manual", "steptronic"]
drivetrain = ["FWD", "RWD", "AWD"]
status = ["new", "used"]
car_maker = ["honda", "toyota", "mercedes", "bmw", "lexus"]
hash = Hash.new
#In this part, we hash the set of features using regex
copyOfLine = line
regex = Regexp.new(/{(.*?)}/)
match_array = copyOfLine.scan(regex)
match_array.each do |line|
hash["features"] = line
end
#Now, we split every comma and start matching fields
newStr = line[0...line.index('{')] + line[line.index('}')+1...line.length]
arrayOfElements = newStr.split(',')
arrayOfElements.each do |value|
if value.include?("km") and !value.include?("/")
hash["km"] = value
elsif type.include?(value)
hash["type"] = value
elsif transmission.include?(value.downcase)
hash["transmission"] = value
elsif value.include?("/") and value.include?("km")
hash["fuel economy"] = value
elsif drivetrain.include?(value)
hash["drivetrain"] = value
elsif status.include?(value.downcase)
hash["status"] = value
elsif /(?=.*[a-zA-Z])(?=.*[0-9])/.match(value) and !value.include?("km")
hash["stock"] = value
elsif car_maker.include?(value.downcase)
hash["carmaker"] = value
elsif /^\d{4}$/.match(value)
hash["year"] = value
elsif value.length == 2
hash["trim"] = value
else
if value.length > 2
hash["model"] = value
end
end
end
end
end
textFile = File.open('cars.txt', 'r')
textFile.each_line{|line|
if line.length > 2
result = Car_model.convertListings2Catalogue(line)
puts "Hash: #{result}"
carObj = Car_model.new(result["km"], result["type"], result["transmission"], result["stock"], result["drivetrain"],
result["status"], result["fuel"], result["carmaker"], result["model"], result["year"], result["trim"], result["features"])
###catalogue.push (carObj)
end
}
This line
result = Car_model.convertListings2Catalogue(line)
Doesn't return the hash object. It returns arrayOfElements since that's what the each method actually returns and the each method is the last method executed in the method (although there are hash assignments within it, it's only the last value that's returned unless you use an explicit return statement.
Just use the variable hash in the last line of the convertListing2Catalog method
if value.length > 2
hash["model"] = value
end
end
end
hash # < this is the last line of the method so it's the value that will be returned
end
end
If you think about it, there were several variables created in the method. There's no reason to expect that the contents of any specific variable such as hash would be returned, and ruby methods by default return the last executed command.
I have run to the following code and I have no idea what it does. Why do they use = to compare values or are they assigning values and checking if the value is true after being assigned?
if value = (key rescue nil)
..
end
This is equivalent to:
value = key rescue nil
if value
..
end
or
value = begin
key
rescue
nil
end
if value
..
end
Remember nil and false are the only two objects that are falsey in ruby and since value here could be nil, that if statement could return false.
If i have following if else statement
if a.present? && b.value == 'N'
b = test
elsif a.present? && b.value == 'Y'
b = guest
end
I can write ternary operation for this
b = (a.present? && b.value == 'N') ? "test" : "guest"
but in this ternary oprator i am not looking for condition b.value == 'Y' and it could be something else 'd' or 'e'.
How do i update ternary operator so it verifies both conditions in if and elsif?
For something like this you might want to use a simple look-up table to eliminate some of the logic:
EQUIVALENT = {
'Y' => 'guest',
'N' => 'test'
}
if (a.present?)
b = EQUIVALENT[b.value] || b
end
The || b part may not be necessary if non-mapped b values are ignored.
b = case b.value
when 'N' then test
when 'Y' then guest
end if a.present?
This is the only DRY answer here so far.
You can use a ternary operator. It doesn't mean you should do it, though:
a.present? && (b.value == 'N' ? b = 'test' : b.value == 'Y' && b = 'guest')
Here's a small test:
class Object
def present?
true
end
end
class NilClass
def present?
false
end
end
a = true
class B
attr_accessor :value
end
b = B.new
b.value = 'Y'
a.present? && (b.value == 'N' ? b = 'test' : b.value == 'Y' && b = 'guest')
p b
# "guest"
I would not insist on the ternary operator but extract the common a.present? test in an outer if and then write the rest of the code using if modifiers:
if a.present?
b = test if b.value == 'N'
b = guest if b.value == 'Y'
end
To me, it seems much easier to read this way.
I am testing small code below
params[:code] = if false
'N'
else
'Y'
end
it returns N for if param[:code] passed as true or false also rubucop shows error literal 'false' appeared in a condition. any idea why?
if false
params[:code] = if false
'N'
else
'Y'
end
This code is just :
params[:code] = 'Y'
No if, not but : false is well, always false, so there's no way N can be reached. That's the reason rubocop is complaining.
Modified code
I guess you meant to write :
params[:code] = if params[:code] == false
'N'
else
'Y'
end
It's not rubyish at all, but at least it looks like your code and does what you expect it to.
To test it :
params = {code: false}
params[:code] = if params[:code] == false
'N'
else
'Y'
end
p params
# {:code=>"N"}
Warning!
If your params values are Strings (as they often are), you'll have to test against Strings :
params[:code] = if params[:code] == "false"
'N'
else
'Y'
end
With a ternary :
params[:code] = params[:code] == "false" ? 'N' : 'Y'
Or a hash :
params[:code] = {'true' => 'Y', 'false' => 'N'}[params[:code]]
If you have a fuzzy input (e.g. true or "true" or "True" or "yes"), you could use Rails built-in methods to convert to boolean :
code = ActiveRecord::Type::Boolean.new.type_cast_from_database(params[:code]) # For Rails 4.2
params[:code] = code ? 'Y' : 'N'
Have you tried this...
params[:code] ? 'Y' : 'N'
Or
params[:code] = params[:code] ? 'Y' : 'N'
# If you are trying to also re-assign params[:code].
If a = false and b = 2 is there a concise way to accomplish this? Using just return a unless b returns 'nil' instead of '2'.
I have
def checkit
return a unless b
b
end
Will this statement call b twice?
A real life case for this is:
def current_user
#current_user ||= authenticate_user
end
def authenticate_user
head :unauthorized unless authenticate_from_cookie
end
def authenticate_from_cookie
.
if user && secure_compare(user.cookie, cookie)
return user
else
return nil
end
end
Try this:
( b == true ) ? a : false
where a is a value you need to return
I do not know why you have false stored in the variable a, so I omitted that. As I understand, you want to pass a value to the method checkit, which should return the value if its boolean value is true (which means everything except values nil and false), and otherwise return the value. In that case, just use this:
def checkit(value)
value || false
end
checkit(1) # => 1
checkit(false) # => false
checkit('value') # => "value"
checkit(nil) # => false