如何在Ruby中使用常量进行映射

时间:2017-02-15 17:40:03

标签: ruby-on-rails ruby

我正在尝试使用已定义的常量映射自定义值数组。我遇到了一些问题。

这非常有效:

Car.where(brand: car_brands.map(&:Car_honda))

虽然我已经在我的文件中定义了所有汽车品牌,但我更倾向于使用常量来重写名称。例如:

HONDA = "Car_honda"

当我尝试将此常量映射到数组时,它似乎无法正常工作:

Car.where(brand: car_brands.map(&:HONDA))

我尝试使用map的块,但我仍然得到相同的结果:

Car.where(brand: car_brands.map {|c| c.HONDA}))

我们是否可以将常量与map一起使用?

5 个答案:

答案 0 :(得分:4)

只需使用send

Car.where(brand: car_brands.map { |c| c.send(HONDA) })

答案 1 :(得分:1)

我不确定你要去哪里,或者确切地说你来自哪里,但这是一个遵循Rails惯例的例子:

class Brand < ActiveRecord::Base
  has_many :cars
end

class Car < ActiveRecord::Base
  belongs_to :brand
end

然后你可以找到所有与“本田”品牌相关的汽车:

Brand.find_by(name: 'Honda').cars

或者使用JOIN操作找到所有匹配一个或多个任意品牌名称的汽车:

Car.joins(:brand).where(brand: { name: %w[ Honda Ford ] })

如果你使用Rails中的流程,事情就容易多了。

答案 2 :(得分:0)

  

您是否可以将常量与地图一起使用?

不。不管怎样,不是这样。

  

car_brands.map { |c| c.HONDA }

这意味着,car_brands中的所有内容都会在其上调用方法 HONDA并返回调用结果。所以,除非你定义了方法HONDA(你绝对不应该这样做),否则没有机会工作。

答案 3 :(得分:0)

常量是在类上定义的,而不是在对象上定义的。您可以通过.class调用它们。

:005 > Integer.const_set('ABC', 1)
 => 1
:006 > Integer::ABC
 => 1
:007 > [1,2,3].map {|i| i.class::ABC}
 => [1, 1, 1]

除非car_brands包含不同Car类的数组,否则这不适用于您的用例。

答案 4 :(得分:0)

首先,你可能不想这样做。也许这就是你的例子措辞的方式,但正如我读的那样,唯一有意义的方法就是Car_brands是一个类的数组。如果是这样的话,那么拥有一个名为HONDA的常量是不合理的。如果有的话,你会得到一个名为BRAND的常数,它可能等于&#34;本田&#34;对于给定的类。我强烈建议您在继续前进之前重新考虑数据结构。

所有这一切,您可以使用const_get来使用map访问常量。 e.g。

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"]