Rails:Messages_Users连接模型运行不正常?

时间:2012-12-04 23:29:09

标签: ruby-on-rails

我正在尝试使用MessageUser创建消息传递系统(已发送消息,已接收消息,发件人,接收者)。由于它是多对多的关系,我有一个名为messages_users

的连接模型

模式:

ActiveRecord::Schema.define(:version => 20121204230411) do

  create_table "messageattachments", :force => true do |t|
    t.string   "picture"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

  create_table "messages", :force => true do |t|
    t.string   "content"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

  create_table "messages_users", :force => true do |t|
    t.integer  "receiver_id"
    t.integer  "sender_id"
    t.datetime "created_at",          :null => false
    t.datetime "updated_at",          :null => false
    t.integer  "sent_message_id"
    t.integer  "received_message_id"
  end

  create_table "users", :force => true do |t|
    t.string   "name"
    t.string   "email"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

end

模型:

class Message < ActiveRecord::Base
  attr_accessible :content

  has_many :messages_users
  has_many :receivers, :through => :messages_users
  has_many :senders, :through => :messages_users

end


class User < ActiveRecord::Base
  attr_accessible :email, :name

  has_many :messages_users
  has_many :sent_messages, :through => :messages_users
  has_many :received_messages, :through => :messages_users
end


class MessagesUsers < ActiveRecord::Base
  attr_accessible :sent_messages_id, :received_messages_id, :receiver_id, :sender_id

  belongs_to :sent_messages, :class_name => "Message", :foreign_key => "sent_message_id"
  belongs_to :received_messages, :class_name => "Message", :foreign_key => "received_message_id"
  belongs_to :receivers, :class_name => "User", :foreign_key => "receiver_id"
  belongs_to :senders, :class_name => "User", :foreign_key => "sender_id"
end

我正在尝试进行一项简单的测试:

require 'test_helper'

class MessageTest < ActiveSupport::TestCase
  test "has senders" do
    message = Message.create(:content => "hi")
    message.sender = User.first #Am I allowed to an instance of another Model in unit tests?
    assert message.sender.valid?
  end

无论我测试什么,我总是得到这个错误:

# Running tests:

E

Finished tests in 0.083961s, 11.9103 tests/s, 0.0000 assertions/s.

  1) Error:
test_has_senders(MessageTest):
ActiveRecord::StatementInvalid: PG::Error: ERROR:  column "receiver_id" of relation "messages" does not exist
LINE 1: INSERT INTO "messages" ("content", "receiver_id", "sender_id...
end

有人可以帮帮我吗?我没有看到我的模型有任何问题..

Loading development environment (Rails 3.2.8)
1.9.3-p194 :001 > message = Message.create(:content => "hi")
   (0.2ms)  BEGIN
  SQL (22.6ms)  INSERT INTO "messages" ("content", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["content", "hi"], ["created_at", Tue, 04 Dec 2012 23:58:19 UTC +00:00], ["updated_at", Tue, 04 Dec 2012 23:58:19 UTC +00:00]]
   (0.8ms)  COMMIT
 => #<Message id: 1, content: "hi", created_at: "2012-12-04 23:58:19", updated_at: "2012-12-04 23:58:19"> 
1.9.3-p194 :002 > message.sender = User.first
  User Load (0.6ms)  SELECT "users".* FROM "users" LIMIT 1
NoMethodError: undefined method `sender=' for #<Message:0x007f92441ac538>
    from /Users/edmundmai/.rvm/gems/ruby-1.9.3-p194@rails3tutorial2ndEd/gems/activemodel-3.2.8/lib/active_model/attribute_methods.rb:407:in `method_missing'
    from /Users/edmundmai/.rvm/gems/ruby-1.9.3-p194@rails3tutorial2ndEd/gems/activerecord-3.2.8/lib/active_record/attribute_methods.rb:149:in `method_missing'
    from (irb):2
    from /Users/edmundmai/.rvm/gems/ruby-1.9.3-p194@rails3tutorial2ndEd/gems/railties-3.2.8/lib/rails/commands/console.rb:47:in `start'
    from /Users/edmundmai/.rvm/gems/ruby-1.9.3-p194@rails3tutorial2ndEd/gems/railties-3.2.8/lib/rails/commands/console.rb:8:in `start'
    from /Users/edmundmai/.rvm/gems/ruby-1.9.3-p194@rails3tutorial2ndEd/gems/railties-3.2.8/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'
1.9.3-p194 :003 > 

2 个答案:

答案 0 :(得分:0)

您的测试数据库似乎尚未正确创建或迁移。

尝试投放rake db:createrake db:migrate RAILS_ENV=test

答案 1 :(得分:0)

你好像混合了单数和复数形式。您有belongs_to :receivers(复数),但您将外键命名为receiver_id

belongs_to :receivers, :class_name => "User", :foreign_key => "receiver_id"

当然,您可以根据需要为这些内容命名,但默认(更明智的,恕我直言)的措辞是命名关联receiver

来自the foreign_key option of belongs_to上的文档:

  

指定用于关联的外键。默认情况下,这被认为是具有“_id”后缀的关联的名称。因此,定义belongs_to:person关联的类将使用“person_id”作为默认值:foreign_key。同样,belongs_to:favorite_person,:class_name =&gt; “Person”将使用“favorite_person_id”的外键。

同样,在您指定message.sender = User.first,但您的Message模型没有sender时,它有senders(复数)。这就是您在控制台NoMethodError: undefined method 'sender=' for #<Message:0x007f92441ac538>中收到错误的原因。

如果您要做的是在邮件中添加发件人并检查邮件是否包含发件人,那么我认为这样可行:

test "has senders" do
  message = Message.create(:content => "hi")
  user = User.create(...)
  message.senders << user
  assert message.senders.first.valid?
end

虽然,老实说,我并没有真正看到这个测试的重点。我也不太明白为什么邮件有多个发件人。这不应该是一个简单的一对多关系吗?即消息has_one :sender。这对我来说很有意义。事实上,这里的整个模型设置有点令人困惑,如果你能澄清为什么你这样设置它会有所帮助。