【问题标题】:Using proper Ruby structures like arrays and hashes to populate data使用适当的 Ruby 结构(如数组和哈希)来填充数据
【发布时间】:2013-02-16 17:47:33
【问题描述】:

要在 Rake 任务 curretnyl 中填充一些示例数据,我有这样的方法:

def create_population_summaries
  PopulationSummary.where(year: 2009).first_or_create(member_count: 12, organization_id: 1)
  PopulationSummary.where(year: 2010).first_or_create(member_count: 5, organization_id: 1)
  PopulationSummary.where(year: 2011).first_or_create(member_count: 99, organization_id: 1)
  PopulationSummary.where(year: 2008).first_or_create(member_count: 52, organization_id: 1)
  PopulationSummary.where(year: 2012).first_or_create(member_count: 30, organization_id: 1)
  PopulationSummary.where(year: 2013).first_or_create(member_count: 25, organization_id: 1)
  PopulationSummary.where(year: 2008).first_or_create(member_count: 46, organization_id: 1)
end

所以这意味着有一个 PopulationSummary 表,其中包含类似

的列
member_count
year
organization_id

我们已经用老板的数据填充了它们!给了我。

现在我想重构它,使其使用一些 Ruby 结构,如哈希、数组,甚至哈希数组等...这样重构我的方法后 不会 在方法中包含那些手动输入的数据,并且这些手动输入的数据应该来自那个 Ruby 结构、哈希等......仍然在方法中我可以手动输入数据库字段的名称,比如年份, member_count 等...但是我想从 ruby​​ 数据结构中读取的值..

您建议如何编写该数据结构?

【问题讨论】:

标签: ruby-on-rails ruby


【解决方案1】:
data = [{'year'=>2009, 'members'=>12}, {'year'=>2010, 'members'=>5}....]

然后循环

data.each do |d|
  PopulationSummary.where(year: d['year']).first_or_create(member_count: d['members'], organization_id: 1)   
end

【讨论】:

  • hmm 有没有办法在第一个数组中摆脱重复的 "year" 、 "members"... 并保持干燥?
  • 当然,你可以这样做,但随后你会问自己“wtf 是那个充满数字的数据结构”和“did 是 d 的成员数[1] 或 organization_id”。善待未来的自己和跟随你的工程师:使用有意义的数据结构。
  • 我也同意你的观点。我们能否以某种方式将其写成类似于哈希的方式,即哈希的键是年份,而哈希的值是 2009、2010 等?我们可以这样写吗?你觉得呢?
【解决方案2】:

类似的东西呢:

DATA = [[ 2009, 12, 1], 
        [ 2010,  5, 1], 
       ... ]

DATA.each do |d|
  PopulationSummary.where(year: d[0]).first_or_create(member_count: d[1], organization_id: d[2])
end

【讨论】:

  • hmm 更好 :) 为了使其更具可读性,您可以将其更改为使用“哈希”的方式吗?例如一个哈希,它的键是“年”,那么它的值是 2009, 2010 作为它的键的数组? ...只是我的想法..不确定哪个更好...您有什么建议?
  • 您想将数据结构分解为 3 个散列?这可能会开始变得难以维护...总而言之,igor 解决方案更好,因为它是明确的,尽管您需要编写更多文本...
【解决方案3】:

只是出于好奇,您可以将元编程(业务规则,来自老板)和人口本身完全分开:

data = [ {
           'year'=>2009,'members'=>12,'organization_id'=>1
         }, {
           'year'=>2010,'members'=>5,'organization_id'=>1
         }, {
           …
       } ]

然后填充:

data.each do |d| 
  d.inject (PopulationSummary) do |rec, val|
    rec.where val
  end.first_or_create
end

但我担心你会在几个月后老板会带来新的数据时讨厌这个提示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 2014-11-25
    • 1970-01-01
    • 2020-10-09
    相关资源
    最近更新 更多