2

データベースへのアクセスに DataMapper を使用しています。私の目標は、モデルを読み取り専用オブジェクトとして Web サービスに送信することです。これは私の現在の試みです:

class User
  include DataMapper::Resource

  def to_yaml(opts = {})
    mini_me = OpenStruct.new
    instance_variables.each do |var|
      next if /^@_/ =~ var.to_s
      mini_me.send("#{var.to_s.gsub(/^@/, '')}=", instance_variable_get(var))
    end

    mini_me.to_yaml(opts)
  end

  ....
end

YAML::ENGINE.yamler = 'psych'

u = User.get("hulk")
p u.to_yaml
# => "--- !ruby/object:OpenStruct\ntable:\n  :uid: hulk\n  :uidNumber: 1000\n  :gidNumber: 1001\n  :email: hulk@example.com\n  :dn: uid=hulk,ou=People,o=example\n  :name: Hulk\n  :displayName: Hulk\n  :description: Hulk\n  :homeDirectory: /home/hulk\n  :accountFlags: ! '[U          ]'\n  :sambaSID: S-1-5-21-......\nmodifiable: true\n" 

p [ u ].to_yaml # TypeError: can't dump anonymous class Class

これを機能させて例外を取り除く方法はありますか?

ありがとう、クリシー

4

1 に答える 1

2

Usingto_yamlは Psychでは非推奨であり、私のテストでは、このような場合に実際に壊れているようです。

オブジェクトを直接呼び出すとto_yaml、メソッドが呼び出され、期待する結果が得られます。オブジェクトを含む配列でそれを呼び出すと、Psych はそれをシリアル化しますが、メソッドを正しく処理せずto_yaml、デフォルトのシリアル化に戻ってしまいます。あなたの場合、これにより、エラーの原因となる匿名クラスをシリアル化しようとします。

これを修正するには、encode_with代わりに メソッドを使用する必要があります。シリアル化されたフォームが、生成された yaml で OpenStruct オブジェクトとしてタグ付けされることが重要な場合は、次を使用できますrepresent_object(最初のnilパラメーターは使用されていないようです)。

def encode_with(coder)
  mini_me = OpenStruct.new
  instance_variables.each do |var|
    next if /^@_/ =~ var.to_s
    mini_me.send("#{var.to_s.gsub(/^@/, '')}=", instance_variable_get(var))
  end

  coder.represent_object(nil, mini_me)
end

便宜上 OpenStruct を使用しているだけの場合、代替手段は次のようになります。

def encode_with(coder)
  instance_variables.each do |var|
    next if /^@_/ =~ var.to_s
    coder[var.to_s.gsub(/^@/, '')]= instance_variable_get(var)
  end
end

Datamapper には、モデルの yaml シリアライゼーションを提供する独自のシリアライザー プラグインがあることに注意してください。調べる価値があるかもしれません。

于 2012-09-28T23:11:10.637 に答える