繁体   English   中英

ActiveModel :: Serializer无法正常工作

[英]ActiveModel::Serializer not working

我的控制器中有一个Client模型和一个方法,应该返回最近的客户端。 我正在使用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>

这不起作用,因为您的控制器实际上没有使用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调用中的其他args所示),则必须将已经存在的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

使用ActiveModel :: Serializers(AMS)时,您应该只使用:

render json: @post

序列化器的全部目的是将json结构移出控制器。 因此,让我们从摆脱render调用中的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查询将降低服务器的速度,并可能导致其内存不足。 有关可能的解决方案,请参见导轨指南

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM