Create controller tests for Mongoid embedded models

I'm working on a Rails 3 app that allows users to follow movies by adding them to their queue, so that they're notified when the movies are premiering.

Since I'm using Mongoid, I've structured it so that when a user adds a movie to their queue, they create an embedded document, adds, and they also increment an add_counter on the Movie model by 1.

I've been able to get my specs to pass confirming that this behavior is working in the model level, but now that I'm building the controller, I can't seem to get a passing response. I've been looking everywhere for a solution and even after sleeping on it and coming back to it I haven't been able to figure out what I'm doing wrong.

Here is my controller spec:

# spec/controllers/adds_controller_spec.rb

require 'spec_helper'

describe AddsController do

  before(:each) do
    @user = Factory(:user)
    @movie = Factory(:movie)
  end

  describe '#create' do

    context 'given valid params' do

      before(:each) do
        sign_in @user
      end

      it "creates a new add" do
        add_count @user.adds.count
        post :create, :movie_id => @movie.id
        @user.adds.count.should == add_count + 1
      end

    end
  end
end

Here's my controller:

# controllers/adds_controller.rb    

class AddsController < ApplicationController
  before_filter :authenticate_user!

  def create
    @movie = Movie.find(params[:movie_id])
    @user = current_user
    @user.add_to_queue!(@movie)

    respond_to do |format|
      format.js
    end
  end
end

And here are my models:

# models/movie.rb

class Movie
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::MultiParameterAttributes

field :add_counter, :type => Integer, :default => 0

# models/user.rb

class User
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::MultiParameterAttributes

embeds_many :adds

def add_to_queue!(movie)
  if already_added?(movie) == false
    adds.create!(:movie_id => movie.id)
    movie.add_counter += 1
  end
end

def already_added?(movie)
  adds.where(:movie_id => movie.id).exists?
end

# models/add.rb

class Add
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::MultiParameterAttributes

field :movie_id, :type => String
key   :movie_id

embedded_in :user

Finally, here's the feedback from Rspec when I run the controller test:

Failures:

  1) AddsController#create given valid params creates a new add
     Failure/Error: @user.adds.count.should == 1
       expected: 1
            got: 0 (using ==)
     # ./spec/controllers/adds_controller_spec.rb:25:in `block (4 levels) in <top (required)>'

Answers


This code is overly complex. I would get rid of the Add class. The concept of adding should not be modeled by a object but by a relation.

Make two classes (simplified):

movie.rb

class Movie
    include Mongoid::Document
    has_and_belongs_to_many :user_queues, :class_name => "User", :inverse_of => :movie_queue
end

user.rb

class User
    include Mongoid::Document
    has_and_belongs_to_many :movie_queue, :class_name => "Movie", :inverse_of => :user_queues
end

Syntax may not be exact here but treat them like arrays and you'll be golden.


Need Your Help

Are the I and J registers special in DCPU-16?

assembly dcpu-16

DCPU-16 includes 8 general registers named A, B, C, X, Y, Z, I and J. It's a bit of a programmer "trope" to use I and J for loop counters. In DCPU-16, are I and J specialized registers, that shoul...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.