2017-02-01 25 views
6

Rozwijam aplikację przy użyciu JHispter 3.12.2.JHipster: Rejestracja użytkownika z dodatkowymi informacjami

Ponieważ potrzebowałem więcej informacji niż dostarcza JHipster, utworzyłem jednostkę UserExtra zawierającą dwa ciągi: numer telefonu i adres skype. Połączyłem ten obiekt z JHI_User w relacji jeden do jednego.

Teraz napotykam problem, kiedy użytkownik rejestruje się, chcę utworzyć nową UserExtra powiązaną z zarejestrowanym użytkownikiem.

Aby to osiągnąć, wypróbowałem kilka rzeczy po stronie klienta.

Sposób działania standardowej strony rejestru JHipster polega na użyciu zmiennej o nazwie vm.registerAccount, która zawiera imię, nazwisko, login, hasło i tak dalej.

Próbowałem użyć innej zmiennej vm.userExtra trzymając mój numer telefonu i skype. Następnie próbowałem kilka rzeczy:

  • W tych register.controller.js, zdałem userExtra do funkcji Createaccount:

    Auth.createAccount(vm.registerAccount, vm.userExtra).then(function() { 
            vm.success = 'OK'; 
           }).catch(function (response) { 
            vm.success = null; 
            if (response.status === 400 && response.data === 'login already in use') { 
             vm.errorUserExists = 'ERROR'; 
            } else if (response.status === 400 && response.data === 'e-mail address already in use') { 
             vm.errorEmailExists = 'ERROR'; 
            } else { 
             vm.error = 'ERROR'; 
            } 
           });
  • I zmodyfikowano funkcję Createaccount z auth.service.js śledzić zmiany dokonane:

    function createAccount (account, userExtra, callback) { 
          var cb = callback || angular.noop;

     return Register.save(account, userExtra, 
          function() { 
           return cb(account); 
          }, 
          function (err) { 
           this.logout(); 
           return cb(err); 
          }.bind(this)).$promise; 
        }</pre> 
    
  • Wreszcie zaktualizowane funkcję registerAccount z AccountResource.java po stronie serwera:

    public ResponseEntity registerAccount(@Valid @RequestBody ManagedUserVM managedUserVM, UserExtra userExtra) { ... }

ale funkcja nie została jeszcze registerAccount wykonany z tego co pamiętam.

Próbowałem też dodanie nowego użytkownika w zwrotnego funkcji Createaccount z register.controller.js tak:

Auth.createAccount(vm.registerAccount).then(function (result) { 
       vm.userExtra.user = result; 
       UserExtra.save(vm.userExtra, function() { // success }, function() { // fail }); 
       vm.success = 'OK'; 
      })... 

Ale ja tylko otrzymuję błąd podczas próby zapisania nowego UserExtra.

Jestem całkiem pewny, że muszę zmodyfikować funkcję registerAccount() wewnątrz AccountResource.java, ale po prostu nie mogę odzyskać dodatkowych informacji, które próbuję wysłać od strony klienta. Udało mi się utworzyć nowego użytkownika w tej funkcji i połączyć go z JHI_User, ale bez dodatkowych informacji.

Jest bardzo prawdopodobne, że ktoś już stanął w obliczu tego problemu, co może być najlepszym rozwiązaniem tego problemu?

Edit roztworem:

Dzięki Gaël Marziou, poprawiłem mój problem.

Here's a minimal example of a project używając rozwiązania, które opisuję tutaj.

Po stronie klienta, na stronie register.html, którą przepisałem do mojego użytku, mam dwa pola powiązane z vm.Właściwości registerAccount:

<input class="form-control" id="phone" ng-model="vm.registerAccount.phone" placeholder="{{'global.form.phone.placeholder' | translate}}" /> 
... 
<input class="form-control" id="skype" ng-model="vm.registerAccount.skype" placeholder="{{'global.form.skype.placeholder' | translate}}" /> 

W ManagedUserVM naprawdę tylko dodaje moje dwa pola i ich pobierające:

private String phone; 

private String skype; 

public String getPhone() { 
    return phone; 
} 

public String getSkype() { 
    return skype; 
} 

zmieniłem klasę UserExtra do mapowania użytkowników i identyfikatory UserExtra tak, że są dublowane. To przyspiesza proces pobierania i sprawia, że ​​bardziej sensowne jak UserExtra naprawdę jest po prostu przedłużeniem do Użytkownik:

public class UserExtra implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    private Long id; 

    @Column(name = "phone") 
    private String phone; 

    @Column(name = "skype") 
    private String skype; 

    @OneToOne 
    @MapsId 
    private User user; 
    ... 
} 

stworzyłem nową funkcję niestandardową nazwie createuser() w UserService która potrzebuje moich dwóch pól oprócz tych podstawowych. Nie zaktualizować istniejącą funkcję tak, że nie trzeba zmieniać klasy testowe:

public User createUser(String login, String password, String firstName, String lastName, String email, 
         String langKey, String phone, String skype) { 

    User newUser = new User(); 
    Authority authority = authorityRepository.findOne(AuthoritiesConstants.USER); 
    Set<Authority> authorities = new HashSet<>(); 
    String encryptedPassword = passwordEncoder.encode(password); 
    newUser.setLogin(login); 
    // new user gets initially a generated password 
    newUser.setPassword(encryptedPassword); 
    newUser.setFirstName(firstName); 
    newUser.setLastName(lastName); 
    newUser.setEmail(email); 
    newUser.setLangKey(langKey); 
    // new user is not active 
    newUser.setActivated(false); 
    // new user gets registration key 
    newUser.setActivationKey(RandomUtil.generateActivationKey()); 
    authorities.add(authority); 
    newUser.setAuthorities(authorities); 
    userRepository.save(newUser); 
    userSearchRepository.save(newUser); 
    log.debug("Created Information for User: {}", newUser); 

    // Create and save the UserExtra entity 
    UserExtra newUserExtra = new UserExtra(); 
    newUserExtra.setUser(newUser); 
    newUserExtra.setPhone(phone); 
    newUserExtra.setSkype(skype); 
    userExtraRepository.save(newUserExtra); 
    userExtraSearchRepository.save(newUserExtra); 
    log.debug("Created Information for UserExtra: {}", newUserExtra); 

    return newUser; 
} 

Wreszcie zaktualizowane funkcję registerAccount() z AccountResource zadzwonić do mojego niestandardową funkcję wykorzystując dwa dodatkowe pola:

public ResponseEntity<?> registerAccount(@Valid @RequestBody ManagedUserVM managedUserVM) { 

    HttpHeaders textPlainHeaders = new HttpHeaders(); 
    textPlainHeaders.setContentType(MediaType.TEXT_PLAIN); 

    return userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase()) 
     .map(user -> new ResponseEntity<>("login already in use", textPlainHeaders, HttpStatus.BAD_REQUEST)) 
     .orElseGet(() -> userRepository.findOneByEmail(managedUserVM.getEmail()) 
      .map(user -> new ResponseEntity<>("e-mail address already in use", textPlainHeaders, HttpStatus.BAD_REQUEST)) 
      .orElseGet(() -> { 
       User user = userService 
        .createUser(managedUserVM.getLogin(), managedUserVM.getPassword(), 
         managedUserVM.getFirstName(), managedUserVM.getLastName(), 
         managedUserVM.getEmail().toLowerCase(), managedUserVM.getLangKey(), 
         managedUserVM.getPhone(), managedUserVM.getSkype()); 

       mailService.sendActivationEmail(user); 
       return new ResponseEntity<>(HttpStatus.CREATED); 
      }) 
    ); 
} 
+0

Witam @ Paul-Etienne, Właśnie widziałem twoją wskazówkę na stronie jhipstera. Jedno pytanie: czy mógłbyś przesłać minimalny kompletny przykład na Github lub coś podobnego? Próbowałem tego samego mając bazę danych Postgresql i najnowszego jhipstera z opcją --skip-client, tutaj, ale to nie zadziałałoby, a teraz zadaję sobie pytanie, czy czegoś brakuje, np. "Czy muszę zadeklarować" @OneToOne 'w encji użytkownika? Czy encje są tworzone przy pomocy generatora lub ręcznie? Czy encja UserExtra potrzebuje adnotacji' @ Entity' i podobnych pytań. Byłoby wspaniale! –

+1

Witam @ getoverit-DE, nie będę miał dzisiaj czasu, aby naprawdę zagłębić się w twoją prośbę, ale powinienem mieć czas, aby to zrobić jutro. –

+0

hi @ Paul-Etienne, byłoby to absolutnie wspaniałe, dziękuję! –

Odpowiedz

1

ManagedUserVM jest model widok więc najprostszym sposobem jest dodać dodatkowe pola do niego, model widok może być sumą kilku podmiotów. W ten sposób nie zmienisz swojej usługi kątowej, twój kod klienta nie musi wiedzieć, w jaki sposób użytkownik jest przechowywany na serwerze.

Następnie na serwerze należy rozważyć modyfikację jednostki UserExtra, aby użyć tego samego identyfikatora co User zamiast wygenerowanego identyfikatora, należy użyć @MapIds. Zobacz ten bardzo nice article w celu uzyskania szczegółowych informacji.

+0

Dziękuję bardzo, zadziałało. Nie wspominałem o tym w moim oryginalnym wpisie, ale już próbowałem dodać pola w ManagedUserVM. Wygląda na to, że jedyną rzeczą, której mi brakowało, było mapowanie identyfikatorów, nawet nie wiedziałem, że to możliwe. Mam teraz tylko jedno przesłuchanie, w jaki sposób serwer wie, które pola wypełnić, zgodnie z tym, co wysyła klient? Naprawdę właśnie dodałem pola i ich pobierające, bez specjalnego konstruktora. Czy to tylko dlatego, że nazwy pól są zgodne? –

+0

Prawdopodobnie, ale powinien zostać zweryfikowany. Czy możesz pokazać jakiś kod? Wydaje mi się również, że warto to udostępnić jako wskazówkę na https://jhipster.github.io/tips/ –

+0

Okej, mam jeszcze jeden problem, który chcę naprawić, zanim pokażę pełny działający kod i wykonam polecenie zapytanie na temat końcówki JHipster. Mogę pobrać mój numer telefonu i konto Skype w funkcji registerAccount() konta AccountResource.java, ale staram się je zapisać w mojej bazie danych. Popracuję nad tym i skontaktuję się z Tobą, gdy zostanie rozwiązany. –