2016-03-26 1 views
0

Я разрабатываю приложение Ruby On Rails, использующее PostgreSQL в качестве базы данных, и у меня возникла проблема.Укажите, какая внешняя таблица ключей будет указана внутри миграции

Вот мой Questions стол (schema.rb):

create_table "questions", primary_key: "hashid", force: :cascade do |t| 
    t.string "title" 
    t.text  "body" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
end 

add_index "questions", ["hashid"], name: "index_questions_on_hashid", unique: true, using: :btree 

где hashid поле (строка) используется вместо числового id поля по умолчанию.

Вот моя миграция как Questions и Comments таблиц:

# Questions migration 
class CreateQuestions < ActiveRecord::Migration 
    def change 
    create_table :questions, id: false do |t| 
     t.text :hashid, primary_key: true 
     t.string :title 
     t.text :body 

     t.timestamps null: false 
    end 

    add_index :questions, :hashid, unique: true 
    end 
end 


# Comments migration 
class CreateComments < ActiveRecord::Migration 
    def change 
    create_table :comments do |t| 
     t.text :body 
     t.references :question, foreign_key: :hashid 

     t.timestamps null: false 
    end 
    end 
end 

Я хочу связать Comments с Questions в моем приложении, используя belongs_to и has_many отношения соответственно, но по умолчанию t.references :question пытается связать с помощью id колонки из целевой таблицы.

Вот сообщение об ошибке миграции:

== 20160326185658 CreateComments: migrating =================================== 
-- create_table(:comments) 
rake aborted! 
StandardError: An error has occurred, this and all later migrations canceled: 

PG::UndefinedColumn: ERROR: column "id" referenced in foreign key constraint does not exist 
: ALTER TABLE "comments" ADD CONSTRAINT "comments_question_id_fk" FOREIGN KEY ("question_id") REFERENCES "questions"(id) 

Как я могу связать с помощью других, чем id поля? В моем случае это hashid?

+0

Почему вы хотите бороться с соглашениями Rails и не использовать по умолчанию имя 'id' для первичного ключа? Чего вы пытаетесь достичь? – spickermann

+0

Поскольку я пытаюсь создать что-то вроде youtube, у него есть идентификаторы видео как случайные строки, а не числовые идентификаторы, по крайней мере, я так думаю. Вот почему я изменил числовой идентификатор по умолчанию на случайную строку как id –

+0

Вы все равно можете назвать этот столбец 'id', даже если он содержит случайную строку, создаваемую приложением. Если вы выбрали другое имя, вам придется исправить множество разных вещей: миграции, определения первичного ключа класса, маршрутизацию, поисковики ... – spickermann

ответ

1

Я бы предпочел по-прежнему указывать столбец первичного ключа id, даже если столбец содержит случайную сгенерированную строку.

Чтобы создать столбец строки id в вашей базе данных, использовать миграцию как это:

create_table :questions, id: false do |t| 
    # primary key should not be nil, limit to improve index speed 
    t.string :id, limit: 36, primary: true, null: false 
    # other columns ... 
end 

В вашей модели, убедитесь, что id создан:

class Question < ActiveRecord::Base 
    before_validation :generate_id 

private 
    def generate_id 
    SecureRandom:uuid 
    end 
end 

Когда вы уже в Rails 5 вы можете просто использовать has_secure_token :id вместо обратного вызова before_validation и метода generate_id.