I'm trying to map an array of custom values using a constant that's already defined. I'm running into some problems.
This works perfectly:
Car.where(brand: car_brands.map(&:Car_honda))
Although I have all the car brands already defined in my file, so I would prefer to use the constants over rewriting the names. For example:
HONDA = "Car_honda"
When I try and map this constant to the array it doesn't seem to work properly:
Car.where(brand: car_brands.map(&:HONDA))
I tried to use a block with map
, but I still got the same result:
Car.where(brand: car_brands.map {|c| c.HONDA}))
Are we able to use constants with map
?
只需使用send
:
Car.where(brand: car_brands.map { |c| c.send(HONDA) })
I'm not sure where you're going with this, or precisely where you're coming from, but here's an example that follows Rails conventions:
class Brand < ActiveRecord::Base
has_many :cars
end
class Car < ActiveRecord::Base
belongs_to :brand
end
Then you can find all cars associated with the "Honda" brand:
Brand.find_by(name: 'Honda').cars
Or find all cars matching one or more arbitrary brand names using a JOIN
operation:
Car.joins(:brand).where(brand: { name: %w[ Honda Ford ] })
If you go with the flow in Rails things are a lot easier.
Are you able to use constants with map?
Nope. Not like this, anyhow.
car_brands.map { |c| c.HONDA }
This means, for every thing in car_brands
call method HONDA
on it and return results of the invocations. So, unless you have method HONDA
defined (which you absolutely shouldn't), this has no chance to work.
Constants are defined on the class, not on the object. You can invoke them through .class
.
:005 > Integer.const_set('ABC', 1)
=> 1
:006 > Integer::ABC
=> 1
:007 > [1,2,3].map {|i| i.class::ABC}
=> [1, 1, 1]
This will not work for your use case unless car_brands
contains an array of different Car
classes.
First off, you probably don't want to things this way. Perhaps it's the way your example is worded, but the only way it makes sense, as I'm reading it, is if Car_brands
is an array of classes. And if that's the case, if doesn't make sense to have a constant called HONDA
. If anything, you would have a constant called BRAND
that might equal "Honda" for a given class. I strongly recommend you rethink your data structures before moving forward.
All that said, you can use const_get
to access constants using map. eg
class CarBrand1
BRAND = 'Honda'
end
class CarBrand2
BRAND = 'Toyota'
end
car_brands = [CarBrand1, CarBrand2]
car_brands.map{|car_brand| car_brand.const_get("BRAND")}
car_brands.map{|car_brand| car_brand::BRAND} # Alternatively
# => ["Honda", "Toyota"]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.