【问题标题】:How to permit the proper storage of serialized arrays?如何允许正确存储序列化数组?
【发布时间】:2013-10-24 10:59:34
【问题描述】:

我正在使用 Rails 4.0.0,并且我正在尝试使用 StrongParameters gem 将序列化数组正确存储到允许值的数据库中。也就是说,我有:

# Model class
class Article < ActiveRecord::Base
  serialize :links, Array

  ...
end

# Controller class
class ArticlesController < ApplicationController
  ...

  def update
    ...
    @article.update_attributes(article_params)
    ...
  end


  private

  def article_params
    params.require(:article).permit(<PERMITTED_PARAMETERS>) # Keep reading for more information.
  end
end

从提交的参数来看是:

"links"=>{"0"=>{"name"=>"Web Site Name 0", "url"=>"www.website0.com"}, "1"=>{"name"=>"Web Site Name 1", "url"=>"www.website1.com"}, "2"=>{"name"=>"Web Site Name 2", "url"=>"www.website2.com"}, "3"=>{"name"=>"", "url"=>""}, "4"=>{"name"=>"", "url"=>""}, "5"=>{"name"=>"", "url"=>""}}}

在上面的代码中,代替&lt;PERMITTED_PARAMETERS&gt;,我尝试依次输入以下内容:

:links => [:name, :url]
[:links => [:name, :url]]
{:links => [:name, :url]}
[{:links => [:name, :url]}]

在所有上述情况下,StrongParameters 正确地允许值而不会引发错误,但是在我的数据库中,它始终存储以下序列化数据:

---
- !ruby/hash:ActionController::Parameters
  name: Web Site Name 0
  url: www.website0.com
- !ruby/hash:ActionController::Parameters
  name: Web Site Name 1
  url: www.website1.com
- !ruby/hash:ActionController::Parameters
  name: Web Site Name 3
  url: www.website2.com

!ruby/hash:ActionController::Parameters 是什么意思?这是正确的吗?如果不是,我怎样才能以正确的方式存储数据?是 StrongParameters gem 导致了这种奇怪的行为吗?

注意:在我的系统中似乎一切正常,即使数据是“奇怪的”。

【问题讨论】:

标签: ruby-on-rails database serialization ruby-on-rails-4 strong-parameters


【解决方案1】:

我更喜欢使用自定义编码器,看看

# Model class
class Article < ActiveRecord::Base
  serialize :links, ArticleCoder

  ...
end

和...

class ArticleCoder
  def self.load(data)
    YAML.load(data) unless data.nil?
  end
  def self.dump(data)
    YAML.dump(data.to_a) unless data.nil?
  end
end

让我知道这是否适合你。

【讨论】:

    【解决方案2】:

    如果在未定义 ActionController::Parameters 时将数据加载到 Rails 之外,这可能会导致问题。 除此之外,这意味着您将获得一个 ActionController::Parameters 对象而不是 Hash。 由于它们的行为方式相同,因此您可以类似地使用它们。

    现在,如果您仍然需要哈希,您应该能够在模型中执行以下操作:

    before_save :serialize_to_hash
    def serialize_to_hash
      self.links = self.links.to_hash
    end
    

    【讨论】:

      猜你喜欢
      • 2015-08-15
      • 1970-01-01
      • 2016-06-23
      • 1970-01-01
      • 2013-01-05
      • 2013-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多