在Active Record中使用模型名称的变量

时间:2016-01-13 02:50:34

标签: ruby-on-rails ruby activerecord

我正在编写一个种子文件,它将通过HTTParty进行多次API调用以填充数据库。我正在为几个不同的模型提取相同的信息,我希望能够为所有这些模型使用单一方法。但是,我无法弄清楚如何通过变量引用模型名称。具体来说,我遇到了困难,因为每个都必须属于另一个模型。我尝试过以下方法:

def create_assets(subject, model, geokit_hoods)
  response = HTTParty.get("https://raw.githubusercontent.com/benbalter/dc-maps/master/maps/#{subject}.geojson")
  parsed = JSON.parse(response)
  collection = parsed["features"]
  collection.each do |station|
    coordinates = station["geometry"]["coordinates"].reverse
    point = Geokit::LatLng.new(coordinates[0], coordinates[1])
    geokit_hoods.each do |hood|
      if hood[1].contains?(point)
        hood[0][model].create(coordinates: coordinates, name: station["properties"]["NAME"], address: station["properties"]["ADDRESS"])
        break
      end
    end
  end
end

我通过以下方式致电:

create_assets("metro-stations-district", "metros", geokit_hoods)

hood [0]指的是现有的邻域模型,hood [1]是与该邻域相关联的多边形。代码在引用hood [0] .metros.create(...)时有效,但我正在寻找一种方法使这种方法在许多模型中都有用。

任何想法都将不胜感激!

1 个答案:

答案 0 :(得分:1)

现在,我假设您在变量中拥有的是String,它是表名格式的类名。例如,在你的例子中,你在变量中有metros ...我假设你有一个Metro类,你试图创建它。

如果是这样......你首先需要将小写的表名样式变量("metros")转换为类名称样式,例如"Metro" 注意:这是标题和单数(而不是复数)。

Rails有一个方法可以完全按照你想要的方式对字符串执行此操作:classify例如,你可以使用它:

model_name = hood[0][model] # 'metros'
model_name.classify # 'Metro'

请注意,它仍然只是一个字符串,你不能在一个字符串上调用create ..所以你如何使它成为真正的类? constantize

使用此功能将字符串转换为您尝试查找的实际模型类...然后您可以调用create,例如:

model_name = hood[0][model] # 'metros'
the_klass = model_name.classify.constantize # Metro
your_instance = the_klass.create(...)