ruby-on-rails - 如何将参数的默认反序列化覆盖到模型对象?

标签 ruby-on-rails ruby ruby-on-rails-3

如何覆盖模型对象参数的默认反序列化? 换句话说,如何让 Rails 理解带有蛇形数据库的驼峰式 JSON?

示例:我收到带有字段 fooBar 的参数 Foo 对象,我希望我的 Foo 模型能够理解 fooBar 实际上是数据库字段 foo_bar

"Foo": {
  "fooBar": "hello" /* fooBar is database field foo_bar */
}
class Foo < ActiveRecord::Base
  attr_accessible :foo_bar
end

class FoosController < ApplicationController
  def new
    @foo = Foo.new(params[:foo])
  end

Foo.new(params[:foo]) 假定 params[:foo] 包含 foo_bar。相反,params[:foo] 包含 fooBar(在我的例子中,params 包含 JSON 数据)。

我想要一种干净的方式来处理这种情况,就像模型可以覆盖 as_json 的方式一样:

class Foo < ActiveRecord::Base
  attr_accessible :foo_bar, :another_field

  def as_json(options = nil)
    {
      fooBar: foo_bar,
      anotherField: another_field
    }
  end
end

有一个from_json method inside ActiveModel但当 Foo.new(params[:foo]) 运行时它不会被调用。

我读过好几遍,从模型对象覆盖 initialize 是个糟糕的主意。

最佳答案

Foo.new 对您提供的参数散列所做的所有操作都是迭代该散列中的键和值。如果键是 foo_bar,那么它会尝试用值调用 foo_bar=

如果您定义一个设置self.foo_barfooBar= 方法,那么您将能够传递一个带有键值:fooBar 的散列> 到 Foo.new

少手动,你可以做

class Foo < ActiveRecord::Base
  alias_attribute :fooBar, :foo_bar
end

它为您生成所有额外的访问器。

我不会说重写 initialize 是一件糟糕的事情,但正确地做起来可能很棘手,而且几乎总有一种更简单的方法或一种让您的意图更清晰的方法。

关于ruby-on-rails - 如何将参数的默认反序列化覆盖到模型对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12750125/

相关文章:

javascript - 如何访问 haml 文件中的 javascript 变量的值?

javascript - Rails 选择表单 : displaying and using select form value before submit?

ruby-on-rails - Rails ActiveRecord 验证 : maximum length of a string?

ruby-on-rails - 无法在 Devise Initializer 中访问 ENV

ruby-on-rails - 在 Rspec 中测试创建变量赋值

ruby - 导轨 3 : Ensure before_save callback is called after others

ruby-on-rails - Facebook 图形 API gem

ruby-on-rails - 在 Rails 中使用 sanitize 和 truncate 在元素之间添加空间

sql - Ruby ActiveRecord 和 sql 元组支持

ruby-on-rails - Rails 查询一个 has_many :through conditionally with multiple ids