LoginSignup
0
1

More than 5 years have passed since last update.

Garage::Representer::NonEncodableValueが出たとき

Posted at

このエラーが出たときは、だいたいGarage::Repesenter忘れなのですが、他のミスの場合もこのエラーが出るので、ググった時に引っかかるよう書いておきます。

前置き

code.rb
class User < ApplicationRecord
  include Garage::Representer
  has_many :group_user
  has_many :groups, through: :group_user

  property :id
  property :name
  property :groups
end

class Group < ApplicationRecord
  include Garage::Representer
  has_many :group_user
  has_many :users, through: :group_user

  property :id
  property :name
  property :groups
end

class UsersController < ApplicationController
  def require_resource
    @resource = User.find_by(id: params[:id])
  end
end

こんな風のコードがあるとします。

問題

Postsを取得するために GET /users/10 するとこんな感じのエラーが出ます。困った...。

Garage::Representer::NonEncodableValue in UsersController#show
Groups::ActiveRecord_Associations_CollectionProxy can not be encoded directly. Forgot to include Garage::Representer?

ハマってしまい困っていたんですが、間違いはシンプルでUserproperty :groupsが、collection :groupsになるべきでした。

おまけ

最初、挙動がよく分からずコードを追ってしまっていました。このあたりの動きはgarage/representerを読むと書いてあったので共有です。

include Garage::Representerした時にextendされるクラスメソッドがClassMethodで定義され、self.included(base)で適用されます。(これよくあるパターンぽい)

garage/representer.rb
module Garage::Representer
  def self.included(base)
    self.representers << base

    base.class_eval do
      if Rails.application
        include Rails.application.routes.url_helpers
      end
      extend ClassMethods
    end
  end

  module ClassMethods
    attr_writer :representer_attrs

    # ...

    def representer_attrs
      @representer_attrs ||= []
    end

    def property(name, options={})
      representer_attrs << Definition.new(name, options)
    end

    def collection(name, options={})
      representer_attrs << Collection.new(name, options)
    end

    # ...
  end

  # ...

  class Collection < Definition
    def encode(object, responder, selector = nil)
      value = object.send(@name)
      value.map do |item|
        encode_value(item, responder, selector)
      end
    end
  end
end

モデルのハッシュが必要になった場合、Definition#encode_valueでhashへ変換作業をしているのですが、ここでコケていたという雰囲気です。

Collectionの場合はmapしながらhashへの変換をしていくので、ActiveRecord_Associations_CollectionProxyでも問題ないですね。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1