Chapter 12. Movies 2.0 - Adding social

But this was just a plain old movie database (POMD). Our idea of socializing this business wasn't yet realized.

12.1. Look, mom a Cineast! - Users

So we took the User class that we'd already coded and made it a full fledged Spring Data Graph member. We added the ability to make friends and to rate movies. With that there was also a simple UserRepository that was able to look up users by id.

@NodeEntity
class User {
    @Indexed
    String login;
    String name;
    String password;
    @RelatedTo(elementClass=Movie.class, type="RATED")
    Set<Rating> ratings;

    @RelatedTo(elementClass=User.class, type="FRIEND")
    Set<User> friends;

    public Rating rate(Movie movie, int stars, String comment) {
        return relateTo(movie, Rating.class, "RATED").rate(stars, comment);
    }
    public void befriend(User user) {
        this.friends.add(user);
    }
}
@RelationshipEntity
class Rating {
    @StartNode User user;
    @EndNode Movie movie;
    int stars;
    String comment;
    public Rating rate(int stars, String comment) {
       this.stars=stars; this.comment = comment;
       return this;
    }
}
            

We extended my DatabasePopulator to add some users and ratings to the initial setup.

@Transactional
public List<Movie> populateDatabase() {
    Actor tomHanks = new Actor("1", "Tom Hanks").persist();
    Movie forestGump = new Movie("1", "Forrest Gump").persist();
    tomHanks.playedIn(forestGump,"Forrest");

    User me = new User("micha", "Micha", "password", User.Roles.ROLE_ADMIN,User.Roles.ROLE_USER).persist();
    Rating awesome = me.rate(forestGump, 5, "Awesome");

    User ollie = new User("ollie", "Olliver", "password",User.Roles.ROLE_USER).persist();
    ollie.rate(forestGump, 2, "ok");
    me.addFriend(ollie);
    return asList(forestGump);
}
            

12.2. Beware, Critics - Rating

We also put a ratings field into the movie to be able to show its ratings. And a method to average its star rating.

class Movie {
    @RelatedToVia(elementClass=Rating.class, type="RATED", direction = Direction.INCOMING)
    Iterable<Rating> ratings;

    public int getStars() {
        int stars, int count;
        for (Rating rating : ratings) {
            stars += rating.getStars(); count++;
        }
        return count == 0 ? 0 : stars / count;
    }
}
            

Fortunately our tests highlighted the division by zero error when calculating the stars for a movie without ratings. Next steps were to add this information to the UI of movie and create a user profile page. But for that to happen they must be able to log in.