15

I have the following migration

class CreateBooking < ActiveRecord::Migration[5.1]
  def change
    create_table :bookings do |t|
      t.integer :day_period, default: 0
      t.references :service, foreign_key: true, unique: true, dependent: :destroy, index: true
    end
  end
end

and it generates the following schema:

  create_table "bookings", force: :cascade do |t|
    t.integer "day_period", default: 0
    t.bigint "service_id"
    t.index ["service_id"], name: "index_bookings_on_service_id"
  end

When I run guard which runs a consistency_fail test which fails with:

There are calls to has_one that aren't backed by unique indexes.
----------------------------------------------------------------
Model          Table Columns
----------------------------------------------------------------
Service  bookings (service_id)
----------------------------------------------------------------

Now originally I didn't have unique: true but I rolled back and added it in, still the same problem, again, didn't have index: true so I rolled back and added that in and still the same problem.

I think it's becuase service_id in the schema doesn't have unique: true on it but I don't know and I can't find any information on my specific problem.

What causes this problem, what am I doing that is causing this problem and what can I do to stop this problem, given the current migration?

Thermatix
  • 2,757
  • 21
  • 51
  • 1
    Where on the internet did you read that you can pass this parameter like `t.references unique: true`? The uniqueness is a property of the index, not the reference itself. So for example, you *can* pass the parameter like that for `t.add_index`: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_index – Tom Lord Jul 26 '18 at 10:18
  • 1
    @TomLord To be honest, I don't know and also my rails-fu is still less then stellar. – Thermatix Jul 26 '18 at 11:06

1 Answers1

41
t.references :service, foreign_key: true, dependent: :destroy, index: {unique: true}

More about creating references

Leo
  • 1,673
  • 1
  • 13
  • 15
  • This worked, so thanks, question, is it possible in future to make so I can change it from `has_one` to `has_many` if needed? – Thermatix Jul 26 '18 at 11:06
  • 1
    You can change, but can not create more than one assigned object: evoke ActiveRecord::RecordNotUnique – Leo Jul 26 '18 at 11:17
  • 1
    @Thermatix If you think it should be a `has_many`, then I'd make that change sooner rather than later. It could be a real pain to update a large application to use `booking.services` instead of `booking.service` all over the place; the implications are non-trivial. – Tom Lord Jul 26 '18 at 13:55