ActiveModel :: Serializer无法正常工作

我的控制器中有一个客户端模型和一个方法,应该返回最近的客户端。 我正在使用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 = ""; html += ""; html += client_name; html += ""; clients_from_category.html(html); }); }, function() { $(this).children(".category_dropdown").toggle(0, "hidden"); }) }); 

获得输出的html是这样的:

 <img src="https://stackoverflow.com/uploads/picture/image/361/thumbimage.jpb 

使用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查询会降低服务器的速度,并导致内存不足。 请参阅导轨指南以获取可能的解决方

这不起作用,因为您的控制器实际上并没有使用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