【问题标题】:ActiveRecord::StatementInvalid: Mysql2::Error: Table doesn't existActiveRecord::StatementInvalid: Mysql2::Error: 表不存在
【发布时间】:2013-09-12 15:51:45
【问题描述】:

我正在尝试创建简单的内部消息传递服务,我已使用设计进行身份验证,因此我有用户表。我为消息创建了一个消息表和一个名为 messages_users 的连接表。我想通过关联使用has_many,所以我的关联是这样的:-

user.rb :-

has_many :sent_messages, class_name: "Message", foreign_key: "user_id"
has_many :message_users
has_many :received_messages, through: :message_users, source: :message

message.rb:-

belongs_to :user
has_many :message_users
has_many :receivers, through: :message_users, source:  :user

message_user.rb :-

class MessageUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :message
end

和 schema.rb :-

ActiveRecord::Schema.define(version: 20130912100741) do

create_table "messages", force: true do |t|
  t.text     "subject"
  t.text     "body",       limit: 2147483647
  t.integer  "user_id"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "messages_users", id: false, force: true do |t|
  t.integer "user_id",    null: false
  t.integer "message_id", null: false
end

add_index "messages_users", ["message_id"], name: "index_messages_users_on_message_id",       using: :btree
add_index "messages_users", ["user_id"], name: "index_messages_users_on_user_id", using: :btree 
create_table "users", force: true do |t|
  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
  t.datetime "current_sign_in_at"
  t.datetime "last_sign_in_at"
  t.string   "current_sign_in_ip"
  t.string   "last_sign_in_ip"
  t.string   "confirmation_token"
  t.datetime "confirmed_at"
  t.datetime "confirmation_sent_at"
  t.string   "unconfirmed_email"
  t.integer  "failed_attempts",        default: 0
  t.string   "unlock_token"
  t.datetime "locked_at"
  t.string   "authentication_token"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.string   "provider"
  t.string   "uid"
  t.string   "name"
end

add_index "users", ["authentication_token"], name: "index_users_on_authentication_token", unique: true, using: :btree
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
add_index "users", ["unlock_token"], name: "index_users_on_unlock_token", unique: true, using: :btree

end

当我使用 user_object.sent_messages 时它工作正常,但是当我使用 user_object.received_messages 时它给了我 Mysql2::Error: Table 'to_do.message_users' 不存在:SHOW FULL FIELDS FROM 消息用户 ActiveRecord::StatementInvalid: Mysql2::Error: Table 'to_do.message_users' 不存在 错误。我只想通过而不是 habtm 使用 has_many。这里有几个关于 stackoverflow 的问题,但没有一个能解决我的问题,所以有什么建议吗?

【问题讨论】:

  • 您是否尝试过重命名我在回答中提到的表格?

标签: ruby-on-rails ruby-on-rails-3 activerecord associations has-many-through


【解决方案1】:

在 Rails 中,我们依靠“约定优于配置”来定义这里的许多魔法。这里发生的情况只是对“通过”模型的多元化存在一些混淆。

试试这个:

用户.rb

has_many :sent_messages, class_name: "Message", foreign_key: "user_id"
has_many :messages_users
has_many :received_messages, through: :messages_users, source: :message

message.rb

belongs_to :user
has_many :messages_users
has_many :receivers, through: :messages_users, source:  :user

messages_user.rb

class MessagesUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :message
end

schema.rb - 与“create_table messages_users”相同...

基本上,Rails 中的约定是:

  • 模型名称必须始终为“Singular”(即 MessagesUser)
  • 数据库和集合名称将始终为“复数”(即messages_users)

其中令人困惑的部分是您的模型名称是两个单词的串联,因此其中一个是复数形式而另一个不是复数的事实可能会令人困惑。你可以这样保留它,或者简单地用一个词来定义“通过”模型。

尝试用诸如“用户通过收件箱收到许多消息”之类的文字说出来。在这种情况下,您的“直通”模型可以称为收件箱(带有复数的收件箱)。

无论哪种方式,只要您遵守约定,它就会起作用 :) 希望这会有所帮助!

【讨论】:

  • @SabyasachiGhosh 啊对不起我的错..但它仍然没有解决错误
  • 为receive_messages提供类名和外键
  • @SabyasachiGhosh 我可能是错的,因为我对 Rails 还很陌生,但没有 source 选项为我们做这件事……我之前尝试过在没有 source 的情况下传递 class_name 和 foreign_key 选项,它给了我类似 nosourcemethod 错误
  • 这可能是一个愚蠢的问题,但您是否在创建 message_users 迁移后运行了 rake db:migrate?
  • 无法弄清楚实际检查什么查询轨道尝试运行并在 mysql 中运行相同。并尝试找出错误
【解决方案2】:

对于这个用户和消息,我只有两个模型。

在消息中,我会给出两个字段 sender_id 和 received_id。

【讨论】:

    猜你喜欢
    • 2014-07-10
    • 2018-03-15
    • 2016-09-13
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 2013-05-29
    相关资源
    最近更新 更多