【问题标题】:ActiveModel::Serializer not workingActiveModel::Serializer 不工作
【发布时间】:2015-06-21 15:59:34
【问题描述】:

我的控制器中有一个客户端模型和一个方法,它应该返回最近的客户端。我正在使用 ActiveModel::Serializers 但它不起作用。

class ClientSerializer < ActiveModel::Serializer
  attributes :id, :name, :path, :url

  def url
    client_url(object)
  end

  def path
    client_path(object)
 end
end

控制器:

def nearby_from_category
    @closest_clients = Client.from_category(params[:category]).
      activated.locateable.all_with_translation(@lang).
      by_distance(origin: remote_ip).limit(2)

    render json: @closest_clients.to_json(include: {
      translations: {only: [:name, :content]},
      pictures: {only: :image}
    })
end

javascript:

$(function () {
  $(".nav_category").hover(function () {
    var category_dropdown = $(this).children(".category_dropdown");
    var clients_from_category = category_dropdown.children(".clients_from_category");
    var category_dropdown.toggle(0, "hidden");

    $.get($(this).data("url"), function(response) {
        var client = response[0];
        var client_name = client['translations'][0]['name'];
        var client_picture = client['pictures'][0]['image']['thumb']['url'];
        var html;

        html = "<a href='+ client.url +' class='nearest_client'>";
        html += "<img src='" + client_picture +"'>";
        html += client_name;
        html += "</a>";
        clients_from_category.html(html);
    });
  }, function() {
    $(this).children(".category_dropdown").toggle(0, "hidden");
  })
});

得到输出的html是这样的:

<a href="undefined" class="nearest_client"><img src="/uploads/picture/image/361/thumbimage.jpb</a>

【问题讨论】:

    标签: javascript ruby-on-rails active-model-serializers


    【解决方案1】:

    这不起作用,因为您的控制器实际上并未使用ActiveModel::Serializer 进行渲染。你需要这样写:

    def nearby_from_category
        @closest_clients = Client.from_category(params[:category]).
          activated.locateable.all_with_translation(@lang).
          by_distance(origin: remote_ip).limit(2)
    
        render json: @closest_clients
    end
    

    如果您想按照to_json 调用中的附加参数指示自定义序列化程序,则必须将已经存在的ClientSerializer 修改为:

    class ClientSerializer < ActiveModel::Serializer
      attributes :id, :name, :path, :url
    
      has_many :translations
      has_many :pictures
    
      def url
        client_url(object)
      end
    
      def path
        client_path(object)
      end
    end
    
    class TranslationSerializer < ActiveModel::Serializer
      attributes :name, :content
    end
    
    class PictureSerializer < ActiveModel::Serializer
      attributes :image
    end
    

    【讨论】:

      【解决方案2】:

      当使用 ActiveModel::Serializers (AMS) 时,您应该简单地使用:

      render json: @post
      

      序列化器的全部意义在于将 json 结构从控制器中移出。因此,让我们从去掉渲染调用中的 include 哈希开始:

      def nearby_from_category
        @closest_clients = Client.from_category(params[:category]).
          activated.locateable.all_with_translation(@lang).
          by_distance(origin: remote_ip).limit(2)
        render json: @closest_clients
      end
      

      在大多数情况下,AMS 可以通过查看内容自行确定将哪个序列化程序用于集合。您可以使用each_serializer 选项手动指定它。

      要包含翻译和图片,您需要重新定义序列化程序:

      class ClientSerializer < ActiveModel::Serializer
        attributes :id, :name, :path, :url
      
        has_many: :translations
        has_many: :pictures
      
        def url
          client_url(object)
        end
      
        def path
          client_path(object)
        end
      end
      
      class TranslationSerializer < ActiveModel::Serializer
        attributes :name, :content
      end
      
      class PictureSerializer < ActiveModel::Serializer
        attributes :image
      end
      

      一个大问题是您可能会创建 N + 1 查询问题,因为除非加入,否则将为每个客户端单独加载关联。这不是 AMS 特有的问题。

      生成的许多 SQL 查询会降低您的服务器速度,并可能导致其内存不足。有关潜在的解决方案,请参阅the rails guides

      【讨论】:

      • maxcal 和 Gavin 都是对的,但我接受了 maxcal 的回答,因为他是第一个。感谢两位!
      • 其实 Gavin 比我快 40 秒 :)
      • 是的,但你和我在上一个问题中达成了协议 :) 对不起 Gavin!
      • @MarkoĆilimković 后台处理 SO 接受的答案运行给版主 &lt;/sarcasm&gt;
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 2017-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多