2015-06-21 80 views
0

我有一個客戶端模型和我的控制器中應該返回最近的客戶端的方法。我使用ActiveModel :: Serializer,但它不起作用。ActiveModel :: Serializer不工作

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> 

回答

1

使用時加載ActiveModel ::串行器(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

+0

maxcal和Gavin都是對的,但我接受了maxcal的答案,因爲他是第一個。感謝這兩個! –

+0

其實加文打我40秒:) – max

+0

是的,但你和我在前面的問題做了一個交易:) 對不起加文! –

2

這不是工作,因爲你的控制器不實際上使用012進行渲染。你需要它這樣寫:

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 
相關問題