我正在尝试使用Message
和User
创建消息传递系统(已发送消息,已接收消息,发件人,接收者)。由于它是多对多的关系,我有一个名为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 >
答案 0 :(得分:0)
您的测试数据库似乎尚未正确创建或迁移。
尝试投放rake db:create
和rake 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
。这对我来说很有意义。事实上,这里的整个模型设置有点令人困惑,如果你能澄清为什么你这样设置它会有所帮助。