title: Rspec: Factory Girl & Complex Associations
body: <p>I am trying to test a helper method that would return the amount of <code>Subscribers</code> a <code>Campaign</code> is targeting. Being fairly new to TDD, I am having a hard time wrapping my head around how to write this one since the associations are quite complex. A <code>Campaign</code> "targets" by whether a subscriber is on the targeted <code>plan</code> and opted-in to the targeted <code>program</code>. </p>
  
  <p>How do I get my Factory Girl objects to be associated with one another in order to continue writing the spec? As simple as it may seem, I can't get them to cooperate.</p>
  
  <p>Here are the model associations..</p>
  
  <p><strong>models/<em>campaign.rb</em></strong></p>
  
  <pre><code>class Campaign &lt; ActiveRecord::Base
      belongs_to :program
      belongs_to :plan
  end
  </code></pre>
  
  <p><strong>models/<em>subscriber.rb</em></strong></p>
  
  <pre><code>class Subscriber &lt; ActiveRecord::Base
      has_many :plans, through: :plannables
  end
  </code></pre>
  
  <p><strong>models/<em>plan.rb</em></strong></p>
  
  <pre><code>class Plan &lt; ActiveRecord::Base
      has_many :subscribers, through: :plannables
      has_many :plannables
      has_many :campaigns
  
      validates :name, presence: true,
                  uniqueness: true
  end
  </code></pre>
  
  <p><strong>models/<em>program.rb</em></strong></p>
  
  <pre><code>class Program &lt; ActiveRecord::Base
      has_many :campaigns
  
      validates :name, presence: true,
                       uniqueness: true
  end
  </code></pre>
  
  <p><strong>models/<em>plannable.rb</em></strong></p>
  
  <pre><code>class Plannable &lt; ActiveRecord::Base
      belongs_to :plans
      belongs_to :subscribers
  end
  </code></pre>
  
  <p>Here are the Factories..</p>
  
  <p><strong>spec/factories/<em>campaign.rb</em></strong></p>
  
  <pre><code>FactoryGirl.define do
  
      factory :campaign do |x|
          x.sequence(:name) { |y| "201#{y} Example" }
          x.sequence(:comment) { |y| "The #{y} example" }
          channels ["Folder", "Fax"]
      end
  
      factory :program do
          name "Sims"
          comment "the sims program"
      end
  
      factory :plan do
          name "PDX"
      end
  end
  </code></pre>
  
  <p><strong>spec/factories/<em>subscribers.rb</em></strong></p>
  
  <pre><code>FactoryGirl.define do
      sequence(:first_name) { |y| "Sam #{y}" }
      sequence(:last_name) { |y| "Sm#{y}th" }
      sequence(:email) { |y| "email#{y}@sub.com".downcase }
  
      factory :subscriber do
          first_name
          last_name
          email
          password "secret123"
          home_duid { SecureRandom.uuid }
          admin false
          sims true  #opt-in status
          cups false  #opt-in status
          tire false #opt-in status
      end
  
  
  end
  </code></pre>
  
  <p>...and my specs..</p>
  
  <p><strong>spec/helpers/<em>application_helper_spec.rb</em></strong></p>
  
  <pre><code>require "rails_helper"
  
  RSpec.describe ApplicationHelper, :type =&gt; :helper do
      before :all do
          @program = create(:program)
          @subscriber = create(:subscriber, star: true)
          @campaign = create(:campaign, plan_id: @plan, program_id: @program)
          @plan = Plan.new(name: "STX)", subscriber_id: @subscriber)
      end
  
      describe "Campaign subscriber listing" do
          it "finds subscribers that opt-in to affiliated program" do
            expect(@campaign.plan_id).to eq @plan
          end
      end
  end
  </code></pre>
  
  <p>Just as a starter, to simply test an association I created above via object ids, I added that first spec - yet I can't even get that to pass.. Any idea what I might be missing?</p>
  
  <p><strong>Failures:</strong></p>
  
  <pre><code> 1) ApplicationHelper Campaign subscriber listing finds subscribers that opt-in to affiliated program
       Failure/Error: expect(campaign.plan).to eq plan
  
         expected: #&lt;Plan id: 3, name: "PDX", created_at: "2015-06-16 20:51:18", updated_at: "2015-06-16 20:51:18", plan_id: nil&gt;
              got: nil
  
         (compared using ==)
       # ./spec/helpers/application_helper_spec.rb:19:in `block (3 levels) in &lt;top (required)&gt;'
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I tried using Factory Girl <code>association</code> in my <code>campaign</code> factory..</p>
  
  <pre><code>factory :campaign do |x|
      x.sequence(:name) { |y| "201#{y} Example" }
      x.sequence(:comment) { |y| "The #{y} example" }
      channels ["Folder", "Fax"]
      association plan
  end
  </code></pre>
  
  <p>But receive a confusing error...</p>
  
  <pre><code>* plan - Validation failed: Name has already been taken
  </code></pre>
  
  <p>I tried changing the name to something random but continuing getting this error. </p>