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

Ruby on rails 如何覆盖模型对象参数的默认反序列化?,ruby-on-rails,ruby,ruby-on-rails-3,Ruby On Rails,Ruby,Ruby On Rails 3,如何覆盖模型对象参数的默认反序列化? 换句话说,如何让Rails通过snake-case数据库理解camel-case JSON 示例:我收到带有字段fooBar的paramsFoo对象,我希望我的Foo模型能够理解fooBar实际上是数据库字段fooBar "Foo": { "fooBar": "hello" /* fooBar is database field foo_bar */ } 存在一个,但在运行Foo.new(params[:Foo])时不会调用它 我已经读过好几次了,从模

如何覆盖模型对象参数的默认反序列化? 换句话说,如何让Rails通过snake-case数据库理解camel-case JSON

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

"Foo": {
  "fooBar": "hello" /* fooBar is database field foo_bar */
}
存在一个,但在运行
Foo.new(params[:Foo])
时不会调用它


我已经读过好几次了,从模型对象重写
初始化
是一个糟糕的主意。

所有
Foo.new
对您给定的参数散列所做的一切都是迭代该散列中的键和值。如果键是
foo\u bar
,则它会尝试使用该值调用
foo\u bar=

如果您定义了一个设置self.fooBar
fooBar=
方法,那么您将能够使用键
:fooBar
将哈希传递到
foo.new

减少手动操作,您可以执行以下操作

class Foo < ActiveRecord::Base
  alias_attribute :fooBar, :foo_bar
end
class Foo
这将为您生成所有额外的访问器


我不会说重写
initialize
是一件可怕的事情,但它可能很难做到正确,而且几乎总是有一种更简单的方法或一种使您的意图更清晰的方法。

Foo.new
对您给出的参数哈希所做的一切就是迭代该哈希中的键和值。如果键是
foo\u bar
,则它会尝试使用该值调用
foo\u bar=

如果您定义了一个设置self.fooBar
fooBar=
方法,那么您将能够使用键
:fooBar
将哈希传递到
foo.new

减少手动操作,您可以执行以下操作

class Foo < ActiveRecord::Base
  alias_attribute :fooBar, :foo_bar
end
class Foo
这将为您生成所有额外的访问器


我不会说重写
初始化
是一件可怕的事情,但它可能很难做到正确,而且几乎总是有一种更简单的方法或一种让您的意图更清晰的方法。

我已经检查了active\u model\u序列化程序、RABL和JBuilder。它们都不允许自定义接收到的JSON格式

有关必须处理wrap_参数的信息,请参见 它可以工作,但代码仍然很难看:我在控制器+序列化程序/模型中获得JSON内容,而不是一个地方

使用wrap_参数的示例:

class EventsController < ApplicationController
  wrap_parameters :event, include: [:title, :start, :end, :allDay, :description, :location, :color]

  def create
    respond_with Event.create(params[:event])
  end
end

我创建了一个要点,展示了如何实现序列化/反序列化:

我已经检查了active\u model\u序列化程序、RABL和JBuilder。它们都不允许自定义接收到的JSON格式

有关必须处理wrap_参数的信息,请参见 它可以工作,但代码仍然很难看:我在控制器+序列化程序/模型中获得JSON内容,而不是一个地方

使用wrap_参数的示例:

class EventsController < ApplicationController
  wrap_parameters :event, include: [:title, :start, :end, :allDay, :description, :location, :color]

  def create
    respond_with Event.create(params[:event])
  end
end

我创建了一个要点,展示了如何实现序列化/反序列化:

即使在使用alias_属性时,ActiveRecord似乎也以一种奇怪的方式处理参数[:foo]。参数[:foo]不包含fooBar,因为它是在ActiveRecord级别定义的fooBar。即使使用alias_属性,ActiveRecord似乎也会以一种奇怪的方式处理参数[:foo]。params[:foo]不包含fooBar,因为它是在ActiveRecord级别定义的fooBar。
class Event < ActiveRecord::Base
  attr_accessible :title, :start, :end, :allDay, :description, :location, :color

  # JSON input allDay is all_day
  alias_attribute :allDay, :all_day

  # JSON input start is starts_at
  # +datetime+:: UNIX time
  def start=(datetime)
    self.starts_at = Time.at(datetime)
  end

  # JSON input end is starts_at
  # +datetime+:: UNIX time
  def end=(datetime)
    self.ends_at = Time.at(datetime)
  end

  # Override the JSON that is returned
  def as_json(options = nil)
    {
      id: id,
      title: title,
      start: starts_at, # ISO 8601, ex: "2011-10-28T01:22:00Z"
      end: ends_at,
      allDay: all_day,
      description: description, # Not rendered by FullCalendar
      location: location,
      color: color
    }
  end
end
class Post
{
    [JsonPropertyAttribute("title")]
    public string Title;
}