2015-06-21 6 views
0

У меня есть модель клиента и метод в моем контроллере, который должен возвращать ближайшие клиенты. Я использую ActiveModel :: Serializers, но он не работает.ActiveModel :: Сериализатор не работает

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

Это не работает, потому что ваш контроллер не на самом деле рендеринг с использованием 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 
Смежные вопросы