ActiveModel::Serializer 不工作
ActiveModel::Serializer not working
我的控制器中有一个客户端模型和一个方法,应该return 最近的客户端。我正在使用 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
调用中附加参数的指示自定义序列化程序,则必须将已经存在的 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 结构移出控制器。因此,让我们从去除渲染调用中的 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。
我的控制器中有一个客户端模型和一个方法,应该return 最近的客户端。我正在使用 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
调用中附加参数的指示自定义序列化程序,则必须将已经存在的 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 结构移出控制器。因此,让我们从去除渲染调用中的 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。