Rails 4 and Ruby 2 are now stable. Some highlights:
Work on this issue will be done in the 'ruby-rails-upgrade' branch.
Unfortunately it looks like FactoryGirl just isn't ready for the transition. In Rails 3, when creating a model that requires other models to exist in a many-to-many relationship (i.e. Bounty requires at least one Personality linking it to a Mood), FactoryGirl saved the new models to the database in an order that would guarantee validity: saving new Mood, then new Bounty, then new Candidacy. Unfortunately in Rails 4, FactoryGirl tries to save the Candidacy before the Bounty, so it fails validation and wrecks the whole Bounty creation operation. I could find no way around this problem.
Since we use FactoryGirl in so many places, this is a blocker for the Rails 4 upgrade. I cherry-picked as many changes as could be backported from the Rails 4 migration branch back to the Rails 3-based master branch, so we at least have some of the updates on our main branch. But Strong Parameters will have to remain on the Rails 4 branch for now.
The Ruby 2.0 migration was completely successful and everyone should now update their system Ruby to Ruby 2.
We can return to the Rails 4 upgrade before we bring our app out of beta and see if it's possible get to Rails 4 when we officially launch.
This issue showed up on master when we updated Rails to get Ruby 2 support, so this is not a FactoryGirl issue as I previously thought. It turns out to be caused by a change in the ActiveRecord API in Rails 3.2.9, where has_one, has_many, and belongs_to associations now require you to specify the property on the associated object that they tie to using :inverse_of. So for example, the association between User and Vote as defined in the User model has to change to
has_many :votes, :inverse_of => :user
and the definition in the Vote model becomes
belongs_to :user, :inverse_of => :votes
Using :inverse_of failed to fix the problem where ActiveRecord saves joiner models before the models being joined. Now I don't know what to do.
Aha, another lead appears, buried deep in another Rails issue thread. Apparently adding inverse_of is only half the solution. The other is to use "validates presence true" on associations and not association IDs. For example, this line in the Candidacy model
validates :artist_id, presence: true
validates :artist, presence: true
The above change to validations fixes saving models with many-to-many joins. Now I'm being blocked by ckeditor, which gives the error "uninitialized constant ActionView::Base::InstanceTag" at the point where it is included in the view. This is a known issue in ckeditor that hasn't been fixed in three months.
In addition, the Rails cache seems to be operating in the test environment, as bounty scores are being cached causing tests on bounty.score to fail.