1

パラメータのデフォルトのデシリアライゼーションをモデルオブジェクトにオーバーライドする方法は? つまり、Rails にキャメル ケースの JSON をスネーク ケースのデータベースで理解させるにはどうすればよいでしょうか。

例: フィールドを持つ paramsFooオブジェクトを受け取り、実際にはデータベース フィールドであることをモデルに理解さfooBarせたいとします。FoofooBarfoo_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_jsonActiveModel 内にメソッドがありますが、実行時に呼び出されませんFoo.new(params[:foo])

initializeモデルオブジェクトからのオーバーライドはひどい考えだと何度か読んだことがあります。

4

2 に答える 2

2

active_model_serializers、RABL、および JBuilder を確認しました。受信した JSON 形式をカスタマイズすることはできません。

そのためには、 wrap_parametersを処理する必要があります。http: //edgeapi.rubyonrails.org/classes/ActionController/ParamsWrapper.html を参照してください場所。

wrap_parameters の使用例:

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

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

そして、私のモデルの中で(フレデリック・チャンはこの部分で正しいです):

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

情報については、ASP.NET MVC (Json.NET を使用) は、非常にエレガントな C# デコレータ属性を使用してそれを行います。

class Post
{
    [JsonPropertyAttribute("title")]
    public string Title;
}

シリアライゼーション/デシリアライゼーションを実装する方法を示す要点を作成しました: https://gist.github.com/3858908

于 2012-10-07T13:19:51.923 に答える
2

Foo.new指定した params ハッシュで行うことは、そのハッシュのキーと値を反復処理することだけです。キーが の場合、値を使用foo_barして呼び出しfoo_bar=を試みます。

fooBar=設定するメソッドを定義すると、キーをself.foo_bar持つハッシュを に渡すことができます。:fooBarFoo.new

少ない手動で、あなたが行うことができます

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

これにより、追加のアクセサーがすべて生成されます。

上書きがひどいことだとは言いませんinitializeが、正しく行うのは難しい場合があり、ほとんどの場合、より簡単な方法または意図をより明確にする方法があります。

于 2012-10-05T16:26:28.097 に答える