title: Rspec rails testing - join table not working
body: <p>(I replicated an isolated example of my issue on github: <a href="https://github.com/diingo/jobs_emps" rel="nofollow">https://github.com/diingo/jobs_emps</a>. It contains just the problematic portion - no views, no controllers, just the models I describe below and the breaking test.)</p>
  
  <p>My code is working on development and production but currently a portion is breaking only in the test environment leaving me unable to test it properly.</p>
  
  <p>Here's what's happening:</p>
  
  <p>I have two models, jobs and employees. Each job has employees that oversee and participate in it as a specific role (employee_type) - Manager or Exective. Employees can be promoted - a manager can be promoted to an executive. But their roles for previous jobs they participated in must remain the same.</p>
  
  <p>A join between employees and jobs (JobsEmployee) keeps track of the employee's role through the <code>employee_type</code> attribute. The join will not update a user's position if it was previously set - this is done with a <code>before_save</code>, as seen here:</p>
  
  <pre><code>    class JobsEmployee &lt; ActiveRecord::Base
        before_save :set_user_type
  
        def set_user_type
          self.user_type ||= self.user.type
        end
      end
  </code></pre>
  
  <p>This works fine in actual use on development and production. If a job is created, with a manager and exective, <code>job.jobs_employees</code> will show one manager and one executive. If a manager is promoted to executive and that job is then updated for whatever reason, <code>job.jobs_employees</code> will still show one manager and one executive.</p>
  
  <p>However, during testing this changes. Upon updating a job, if an employee was promoted, <code>job.jobs_employees</code> shows two executives.</p>
  
  <p>My test is shown below. You can see I abstracted controller create and update methods into models for convenience. You can reference them on the github link: <a href="https://github.com/diingo/jobs_emps/blob/master/app/models/job.rb" rel="nofollow">https://github.com/diingo/jobs_emps/blob/master/app/models/job.rb</a></p>
  
  <pre><code>    RSpec.describe JobsEmployee, :type =&gt; :model do
        before do
          @job_permitted_params = {
            city: "Munich",
            status: "in_progress"
          }
          @manager = Employee.create!(name: "Bob Bobber", type: 'Manager')
          @executive = Employee.create!(name: "Alice Smith", type: 'Executive')
          @job_raw_params = {
            job: {
              manager_id: @manager.id,
              executive_id: @executive.id
            }
          }
        end
  
        it "creates and updates" do
          job = Job.create_with_params(@job_permitted_params, @job_raw_params)
          # This passes:
          expect(job.jobs_employees.map &amp;:employee_type).to include("Manager", "Executive")
          @manager.type = 'Executive'
          @manager.save!
  
          Job.update_with_params(job, @job_permitted_params, @job_raw_params)
          # This breaks in testing but works in production:
          expect(job.jobs_employees.map &amp;:employee_type).to include("Manager", "Executive")
        end
      end
  </code></pre>
  
  <p>I put break points (pry debugger) in <code>JobsEmployee#set_user_type</code> to see what might be happening. It appears like the record in JobsEmployee are deleted before or during a Job update. So instead of seeing that <code>self.user_type</code> is already set in <code>self.user_type ||= self.user.type</code>, it just runs <code>self.user.type</code> again.</p>
  
  <p>Here is the schema. You can also see it in the github link.</p>
  
  <pre><code>    ActiveRecord::Schema.define(version: 20150301232938) do
  
        create_table "employees", force: true do |t|
          t.string   "name"
          t.string   "type"
          t.datetime "created_at"
          t.datetime "updated_at"
        end
  
        create_table "jobs", force: true do |t|
          t.string   "city"
          t.string   "status"
          t.datetime "created_at"
          t.datetime "updated_at"
        end
  
        create_table "jobs_employees", force: true do |t|
          t.string   "employee_type"
          t.integer  "employee_id"
          t.integer  "job_id"
          t.datetime "created_at"
          t.datetime "updated_at"
        end
  
      end
  </code></pre>
  
  <p>I'm not sure why this is happening. Thanks so much for checking out the problem.</p>