2013-03-12 11 views
7

Mam kilka modeli w Rails, które wyglądają mniej więcej tak:boczny załadunek przedmiotów o niestandardowych nazw klas w EmberJS z szynami + active_model_serializers

class Issue < ActiveRecord::Base 
    belongs_to :reporter, class_name: 'User' 
    belongs_to :assignee, class_name: 'User' 
    has_many :comments 
end 

class User < ActiveRecord::Base 
end 

class Comment < ActiveRecord::Base 
end 

z serializers tak:

class IssueSerializer < ActiveModel::Serializer 
    attributes :id 
    embed :ids, include: true 

    has_one :reporter, :embed => :ids 
    has_one :assignee, :embed => :ids 
end 

class UserSerializer < ActiveModel::Serializer 
    attributes :id, :name 
end 

class CommentSerializer < ActiveModel::Serializer 
    attributes :id, :body 
end 

ta produkuje JSON, który wygląda mniej więcej tak:

{ 
    "issues": [ 
    { 
     "id": 6, 
     "reporter_id": 1, 
     "assignee_id": 2, 
     "comment_ids": [ 
     3 
     ] 
    }, 
    ], 
    "comments": [ 
    { 
     "id": 3 
     "body": "Great comment" 
    } 
    ], 
    "reporters": [ 
    { 
     "id": 1 
     "name": "Ben Burton" 
    } 
    ], 
    "assignees": [ 
    { 
     "id": 2 
     "name": "Jono Mallanyk" 
    } 
    ] 
} 

problem polega na tym, że side-załadowany reporterów i przedmioty cesjonariusze JSON nie są rozpoznawane przez Ember jako obiekty użytkownika, a widzę następujący błąd:

Uncaught Error: assertion failed: Your server returned a hash with the key reporters but you have no mapping for it 

Nie chcesz usunąć

embed :ids, include: true 

z mojego IssueSerializer, ponieważ wtedy komentarze nie będą serializowane.

Istnieje kilka potencjalnych sposobów, aby rozwiązać ten problem, że mam wziąć pod uwagę:

  • Jeżeli sposób osadzenia na ActiveModel :: serializer przyjął listę modeli w swojej obejmują opcję, to może filtrować odpowiedź JSON dodawać wyłącznie komentarze poboczne.
  • Model danych Ember można skonfigurować do ładowania użytkowników z "użytkowników", "reporterów" i "cesjonariuszy" ... ale z tego, co wiem, wydaje mi się, że obsługuje tylko jeden klucz dla sideloadAs.
  • Jakoś ignorować/dezaktywować błędy ładowania bocznego nieznanych kluczy (prawdopodobnie najmniej rozsądne podejście).

Czy jest jeszcze jedna opcja, której tu brakuje? Myślę, że może będę musiał napisać poprawkę i wysłać żądanie ściągnięcia do rails-api/active_model_serializers, emberjs/data lub obu.

EDIT: My tymczasowe obejście tego jest zmiana IssueSerializer tylko szeregować identyfikatory dla reportera i cesjonariusza:

class IssueSerializer < ActiveModel::Serializer 
    attributes :id, :reporter_id, :assignee_id 
    embed :ids, include: true 

    has_many :comments, :embed => :ids 
end 
+0

Czy możesz pokazać swój model problemu? –

+0

Twoja odpowiedź poniżej jest zgodna z prawdą. – benburton

+0

Jakiej wersji Ember-danych używasz? –

Odpowiedz

1

Należy czytać this strony. Odcinek Revision 12 wyjaśnia o sideloading danych tego samego typu:

Now, homeAddress and workAddress will be expected to be sideloaded together as addresses because they are the same type. Furthermore, the default root naming conventions (underscore and lowercase) will now also be applied to sideloaded root names.

Twój model powinien wyglądać:

App.Issue = DS.Model.extend({ 
    reporter: DS.belongsTo('App.User'), 
    assignee: DS.belongsTo('App.User'), 
    comments: DS.hasMany('App.Comment') 
}); 

JSON wynik powinien mieć klucz dla użytkowników:

{ 
    "issues": [ 
    { 
     "id": 6, 
     "reporter_id": 1, 
     "assignee_id": 2, 
     "comment_ids": [ 
     3 
     ] 
    }, 
    ], 
    "comments": [ 
    { 
     "id": 3 
     "body": "Great comment" 
    } 
    ], 
    "users": [ 
    { 
     "id": 1 
     "name": "Ben Burton" 
    },{ 
     "id": 2 
     "name": "Jono Mallanyk" 
    } 
    ] 
} 

Ponieważ w swoim Modelu skonfigurowano, że reporter jest typu User, Ember wyszukuje użytkownika w wyniku.

+0

Konwencja, w której Ember oczekuje "użytkowników" jako pobocznej kolekcji modeli użytkowników, jest niezgodna z konwencją active_model_serializers, że obiekty są osadzone na najwyższym poziomie przy nazwie pola. Byłoby wspaniale, gdyby ładował obiekty użytkownika pod "użytkownikami", ale tak nie jest. – benburton

+0

Konwencja dla aktywnych_modeli_serializatorów nadal znajduje się w [mapie drogowej] (https://github.com/emberjs/data#roadmap). Czy nadal masz problem z innym wyjątkiem? –

+0

Rozwiązaniem, które mam w tej chwili, jest po prostu nieobciążanie użytkowników dodatkowymi seriami poprzez serializację identyfikatorów w Wydaniu (zobacz moją edycję powyżej). Oczywiście nie jest to wspaniałe, ponieważ potrzebne jest drugie żądanie, jeśli modele Użytkownika nie znajdują się w sklepie. Po krótkiej refleksji myślę, że to, co robi Ember, jest całkowicie uzasadnione. Myślę, że active_model_serializers ma (może?) Błąd w tym, że serializuje modele na podstawie aliasu, a nie nazwy klasy. – benburton

4

Miałem podobny problem i znalazłem rozwiązanie pod adresem ActiveModel::Serializers readme. Możesz użyć opcji :root.Spróbuj coś takiego dla serializatora emisyjnej:

class IssueSerializer < ActiveModel::Serializer 
    attributes :id 
    embed :ids, include: true 

    has_one :reporter, :root => "users" 
    has_one :assignee, :root => "users" 
    has_many :comments 
end 
+0

Powoduje to wyczyszczenie poprzednio załadowanych obiektów, więc jeśli istnieją raporty użytkownika, które nie są cesjonariuszami, to nie będą działać. Mimo to warto wiedzieć. – zode64

0

miałem ten sam problem, dodając include: false sprawie stowarzyszenia nie załatwi dla mnie.

embed :ids, include: true 
    attributes :id, :title 

    has_many :domains, key: :domains, include: false 
    has_many :sessions, key: :sessions