为了更简单,我有
class User
has_many :questions, trough: votes
has_many :questions #(as the author)
has_many :votes
end
忘记在创建时添加foreign_key,现在我不知道如何将其添加到特定的(has_many through)关联
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 :(得分: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
答案 1 :(得分: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