Rails - 我应该使用哪种数据类型将数组存储在数据库中

时间:2014-01-18 23:43:52

标签: ruby-on-rails database types

我收到了来自GET api调用的回复,该调用在我的数据库中以1:1的比例映射。响应如下:

response =     {
      "status": "live",
      "templates": {},
      "responses": 0,
      "creator": "Marketing",
      "publish_url": "https://fluidsurveys.com/account/surveys/403975/publish/",
      "quota_start_date": null,
      "updated_at": "2014-01-18T16:05:20",
      "online_url": "http://fluidsurveys.com/surveys/marketing/tampa-bob-gilbertson-3084-nme-survey-emai/",
      "deploy_uri": "http://fluidsurveys.com/surveys/marketing/tampa-bob-gilbertson-3084-nme-survey-emai/",
      "settings_url": "https://fluidsurveys.com/account/surveys/403975/settings/",
      "groups": [],
      "quota_end_date": null,
      "offline_url": "http://fluidsurveys.com/surveys/marketing/tampa-bob-gilbertson-3084-nme-survey-emai/offline/",
      "responses_url": "https://fluidsurveys.com/account/surveys/403975/responses/",
      "style_url": "https://fluidsurveys.com/account/surveys/403975/theme/",
      "id": 403975,
      "upgrade_url": "https://fluidsurveys.com/account/surveys/403975/upgrade-version/",
      "name": "Bob Gilbertson 3084453  NME Survey Emai",
      "uri": "https://fluidsurveys.com/api/v2/surveys/403975/",
      "invites_url": "https://fluidsurveys.com/account/surveys/403975/publish/invites/",
      "created_at": "2014-01-17T21:47:52",
      "tags": [
        "austin",
        "nme"
      ],
      "preview_url": "http://fluidsurveys.com/surveys/marketing/tampa-bob-gilbertson-3084-nme-survey-emai/?TEST_DATA=",
      "report_url": "https://fluidsurveys.com/account/surveys/403975/reports/",
      "version": 4.0,
      "updated_at_text": "10:05 am",
      "edit_url": "https://fluidsurveys.com/account/surveys/403975/edit/"
    }

正如您所看到的,我在回复中找到了一些数组。我想将response["tags"]存储在我的Survey模型的数据库中。

然而,当我尝试这个时,我收到一个错误:

TypeError (can't cast Array to string):

我该如何解决这个问题?我应该将数据类型从string更改为其他内容,还是需要做其他事情以允许将数组存储在数据库中?另外,作为奖励,是将数组存储在数据库不良实践中吗?

3 个答案:

答案 0 :(得分:1)

默认情况下,Rails不允许将数组存储在数据库中。您必须使用序列化功能才能执行此操作。我从来没有亲自这样做,因为我没有这么做,但你可以在这里找到更多相关信息:Storing arrays in database using ActiveRecord

答案 1 :(得分:1)

  

另外,作为奖励,将数组存储在数据库不良实践中?

在db中存储数组是非规范化的,这通常是不好的做法,因为它阻止了以sql的关系式声明方式访问它。最佳做法是将数组的元素存储在关联的表中,并为它们写出活动的记录关系,如has_manybelongs_to

答案 2 :(得分:1)

这里有几个选项:

  1. 因为它是我们正在处理的标签,您可以将它们存储为逗号分隔的值,同时仍然具有基于 String 的列:

    person.tags = response['tags'].join(',') # Stores "austin,nme"
    
  2. 如果您希望能够查询单个标签(并对其进行索引),则单独存储标签可能是一个不错的选择。为此,您需要创建一个标记模型,该模型与类具有多对多关系。

  3. 最后,您可以将数组序列化为YAML并将其作为字符串存储在数据库中:

    # When storing
    person.tags = YAML::dump(response['tags'])
    
    # When fetching from the database
    tags = YAML::load(person.tags)
    

    您可以通过将此逻辑移至模型访问者来简化您的工作。假设您将标记保存在 Person 模型下:

    class Person
      def tags=(value)
        self.tags = YAML::dump(value)
      end
    
      def tags
        YAML::load(super)
      end
    end
    
  4. 编辑:我最喜欢的方法是第二个,这主要是因为我喜欢保持我的数据库清洁和结构化。将文档(数组,json,blobs等)存储在数据库中是不错的做法,只要您知道自己在做什么以及为什么要这样做。查看整个 NoSQL vs 结构化数据库辩论。我建议的第一个选项可能会满足您的需求,而不会增加复杂性。

相关问题