可以从哈希生成Rails迁移(模型)吗?

时间:2012-11-20 18:31:13

标签: ruby-on-rails ruby hash model

我想知道是否有一种从哈希创建迁移/模型的方法。例如,我有一个Twitter API响应:

 twitter = {:possibly_sensitive_editable=>true,
 :geo=>nil,
 :text=>"http://t.co/asdf",
 :created_at=>"Tue Nov 20 18:10:31 +0000 2012",
 :possibly_sensitive=>false,
 :in_reply_to_status_id_str=>nil,
 :coordinates=>nil,
 :id_str=>"123456",
 :retweeted=>false,
 :in_reply_to_user_id_str=>nil,
 :in_reply_to_screen_name=>nil,
 :source=>"<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone</a>",
 :entities=>
 {:media=>
    [{:type=>"photo",
     :indices=>[0,
     20],
     :url=>"http://t.co/asdf",
     :expanded_url=>"http://twitter.com/qwerty/",
     :media_url_https=>"https://p.twimg.com/qwerty.jpg",
     :source_status_id_str=>"123456",
     :id_str=>"123456",
     :sizes=>
           {:medium=>{:h=>1003,
                      :w=>600,
                     :resize=>"fit"}}}]}}

如果我想从这个哈希创建一个模型(或者更确切地说是模型),有没有快速的方法呢?我可以想象通过将整个文本解析为文本然后将迁移编写为文本文件来实现它,但怀疑它是最好的方式..

因此,如果我想至少从第一级哈希创建模型(即只是Twitter,而不是媒体) - 有没有一种快速的方法来实现这一目标?嵌套哈希是否可能?

3 个答案:

答案 0 :(得分:2)

是否可能(对于非嵌套哈希)?当然。你走了:

class CreateTweets < ActiveRecord::Migration
  def change
    create_table :tweets do |t|


      twitter = {:possibly_sensitive_editable=>true,
        :geo=>nil,
        :text=>"http://t.co/asdf",
        :created_at=>"Tue Nov 20 18:10:31 +0000 2012",
        :possibly_sensitive=>false,
        :in_reply_to_status_id_str=>nil,
        :coordinates=>nil,
        :id_str=>"123456",
        :retweeted=>false,
        :in_reply_to_user_id_str=>nil,
        :in_reply_to_screen_name=>nil,
        :source=>"<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone</a>"
      }

      twitter.keys.each do |key|
        t.string key
      end


      t.timestamps
    end
  end
end

>> Tweet.new
=> #<Tweet id: nil, possibly_sensitive_editable: nil, geo: nil, text: nil, created_at: nil, possibly_sensitive: nil, in_reply_to_status_id_str: nil, coordinates: nil, id_str: nil, retweeted: nil, in_reply_to_user_id_str: nil, in_reply_to_screen_name: nil, source: nil, updated_at: nil>

这是可取的吗?不...你可以说这些属性都只是字符串,而不是时间戳或布尔值。

但你可以做这个作为基线和调整。不推荐

答案 1 :(得分:0)

是否要根据此响应中的字段名称创建新的模型类和新的数据库表?有一些黑客攻击,我相信你可以。但这不是一个坏主意。

模型和数据库模式通常不会在运行时在应用程序中创建。你不需要这样做。 API通常以非常结构化的格式返回数据,只需要一两分钟的时间来进行迁移以保存您想要的数据,然后您可以使用很长时间。

值得浏览每个字段,考虑为什么要存储它,您希望它是什么数据类型,是否可以丢弃它等等。盲目地将此API响应中的每个字段保存到您的数据库中最终存储大量您永远不会使用的数据。

不要偷懒。创建模型,手动定制迁移,并思考管理该模型所需的数据和代码。值得手工完成。

答案 2 :(得分:0)

根据Jesse的建议,我将其扩展为创建一种(非轨道)/本机ruby生成器。

我的API响应包含一个哈希数组,我的ActiveRecord知识非常有限,只是刚开始使用Rails,所以我猜这里有改进的余地 - 在类型映射和结构中(例如我可能想要遍历所有的内容)数组中的哈希并将其放入地图中,以便我覆盖不同对象中字段的变化。)

# Illustrative structure of activities:
# activities = [{"key"=>"val"},{},{}]

puts "class CreateActivities < ActiveRecord::Migration
  def change
    create_table :activities do |t|"
activities.first.each do |key,val|
  arType = case val
    when Hash,Array
      "RELATION-Determine"
    when Float, Fixnum
      "t.integer"
    when FalseClass, TrueClass
      "t.boolean"
    else
      "t.string"
  end
  puts "      #{arType} :#{key}"
end
puts "      t.timestamps null: false
    end
  end
end"

然后运行$ ruby activities_generator.rb > db/migrate/$(date +"%Y%m%d%H%M%S")_create_activities.rb(如果是linux)