ign/ipl-viper — pull request #75 by yobennett (2013-04-27 02:01:51+00:00)
Title: Grape upgrade; large refactor of endpoints to use Mongoid's built-in functions

We are replacing custom builders and updaters in favor of Mongoid's standard persistence functions. This gives us less code to maintain and makes it easier for new engineers to understand the API.

The biggest challenge in this change is how to deal with nested data. For example, `Team` data in a `Matchup`. Incoming user input for `teams` must be translated from an array of `Hash` objects to an array of `Team` id's. This allows for proper validation. Otherwise, if you set the `teams` relation directly with an `update_attributes` call then validations on the `Matchup` are not called until after invalid `Team` data is set. For example, given a valid `Matchup` with two teams in a best of 5,

```
matchup.update_attributes(:teams => [], :best_of => 3)
```

returns false due to validation checking for at least one team. The
`best_of` value is not set. However, the `teams` attribute will be
set to an *empty array* because it is a autosaving referencing relation.

On the other hand,

```
matchup.update_attributes(:team_ids => [], :best_of => 3)
```

returns false and does not set the `teams` relation to an empty array
nor does it set the `best_of` value either, which is the desired result.

The lesson is that there are some quirks that come with the behavior of Mongoid's persistence methods when it comes to reference relations. This refactor is intended to respond to those quirks with simplicity in mind.