2016-07-28 4 views
0

Чтобы сделать более простым у меня естьвнешние рельсы ключей, как добавить?

class User 
    has_many :questions, trough: votes 
    has_many :questions  #(as the author) 
    has_many :votes 
end 

Забыл добавить foreign_key при создании, теперь я не знаю, как добавить его к конкретному (has_many через) объединение

schema.rb

enable_extension "plpgsql" 

    create_table "answers", force: :cascade do |t| 
    t.text  "body" 
    t.datetime "created_at",     null: false 
    t.datetime "updated_at",     null: false 
    t.integer "question_id" 
    t.integer "user_id" 
    t.boolean "best",  default: false 
    end 

    add_index "answers", ["question_id"], name: "index_answers_on_question_id", using: :btree 
    add_index "answers", ["user_id"], name: "index_answers_on_user_id", using: :btree 

    create_table "attachments", force: :cascade do |t| 
    t.string "file" 
    t.datetime "created_at",  null: false 
    t.datetime "updated_at",  null: false 
    t.integer "attachable_id" 
    t.string "attachable_type" 
    end 

    add_index "attachments", ["attachable_id", "attachable_type"], name: "index_attachments_on_attachable_id_and_attachable_type", using: :btree 

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

    add_index "questions", ["title"], name: "index_questions_on_title", using: :btree 
    add_index "questions", ["user_id"], name: "index_questions_on_user_id", using: :btree 

    create_table "users", force: :cascade do |t| 
    t.string "name" 
    t.datetime "created_at",       null: false 
    t.datetime "updated_at",       null: false 
    t.string "email",     default: "", null: false 
    t.string "encrypted_password",  default: "", null: false 
    t.string "reset_password_token" 
    t.datetime "reset_password_sent_at" 
    t.datetime "remember_created_at" 
    t.integer "sign_in_count",   default: 0, null: false 
    t.datetime "current_sign_in_at" 
    t.datetime "last_sign_in_at" 
    t.inet  "current_sign_in_ip" 
    t.inet  "last_sign_in_ip" 
    end 

    add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree 
    add_index "users", ["name"], name: "index_users_on_name", unique: true, using: :btree 
    add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree 

    create_table "votes", force: :cascade do |t| 
    t.integer "votable_id" 
    t.string "votable_type" 
    t.integer "user_id" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

    add_index "votes", ["user_id", "votable_id"], name: "index_votes_on_user_id_and_votable_id", unique: true, using: :btree 

    add_foreign_key "answers", "questions", on_delete: :cascade 
    add_foreign_key "questions", "users", on_delete: :cascade 
end 
+0

Вы можете оставить 'дб/schema.rb'? – siegy22

+0

Вы имеете в виду user_id в других моделях –

+0

RaVeN 'code'create_table "votes", force:: cascade do | t | t.integer "votable_id" t.string "votable_type" t.integer "user_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end –

ответ

0

Выполнить эту команду на консоли

rails g migration AddForeignKeyToVotes user:references question:references 

Это создаст xxxx_add_foreign_key_to_votes.rb файл под db/migrate/ с следующим содержанием

class AddForeignKeyToVotes < ActiveRecord::Migration 
    def change 
    add_reference :votes, :user, index: true, foreign_key: true 
    add_reference :votes, :question, index: true, foreign_key: true 
    end 
end 
+0

Дело в том, что мне нужен внешний ключ. Я начинающий, и, возможно, я не понимаю. Но цель этого добавления состоит в том, чтобы создать псевдоним, который должен иметь has_many: вопросы, и я хотел бы добавить именованный внешний ключ для их разделения. –

0

Вы действительно нужны внешние ключи?

Многие из разработчиков Rails удобны тем, как Rails обрабатывает отношения в приложении, а не в базе данных.

для Вашего случая:

class User 
    has_many :questions, trough: votes 
    has_many :questions  #(as the author) 
    has_many :votes 

конец

если votes таблица имеет question_id и user_id этого достаточно, чтобы определить отношение без каких-либо внешних ключей, если у вас есть причина и действительно нужно это внешние ключи для определения уровня базы данных.

Прочитано THIS SECTION тщательно, Rails использует Convention over Configuration.

В качестве небольшого примера: как ваша модель User знает, в какой таблице запрашивать и извлекать данные, без какой-либо конфигурации она ищет таблицу с тем же именем users (конвенция) и использует ее, как и для внешних ключей.

Согласно Вашему комментарию у вас есть модель что-то как Stackoverflow, у вас есть User, который может задать Question и может ответить в этом случае вы можете иметь что-то вроде Question:

class User 
    has_many :asked_questions, class_name: 'Question' # user can ask many questions 
    has_many :voted_questions, through: :votes, source: 'question' 
    has_many :votes # to get all votes this user did 
end 

class Question 
    has_many :votes # to get all votes for a question 
    belongs_to :user 
end 

class Vote 
    belongs_to :user 
    belongs_to :question 
end 

База данных будет что-то как:

# Table User 
# Table Question (user_id) 
# Table Vote (user_id, question_id) 

Допустим, вы хотите получить Questions пользователь спросил они это будут:

user = User.first 
user.asked_questions 

если вы хотите получить голоса Questions кто пользователя:

user.voted_questions 
+0

mohamed-ibrahim Мне нужно это для адресации. Возможно, я ошибаюсь, но я хочу задать вопросы в качестве автора и вопросы в качестве избирателя/Это разные ассоциации. –

+0

@ anti-k проверить мой обновленный ответ –

+0

mohamed-ibrahim Спасибо большое! –