0

と を使用してメッセージング システム (送信メッセージ、受信メッセージ、送信者、受信者) を作成しようとしてい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 > 
4

2 に答える 2

0

テスト データベースが正しく作成または移行されていないようです。

走ってみてrake db:createrake db:migrate RAILS_ENV=test

于 2012-12-04T23:39:10.590 に答える
0

単数形と複数形を混同しているようです。(複数)ありますbelongs_to :receiversが、外部キーに名前を付けますreceiver_id

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

もちろん、これらのものに好きな名前を付けることができますが、デフォルトの(そしてより賢明な、私見)言い回しは、関連付けに名前を付けることreceiverです。

foreign_keyオプションbelongs_toに関するドキュメントから:

関連付けに使用する外部キーを指定します。デフォルトでは、これは「_id」サフィックスが付いた関連付けの名前であると推測されます。したがって、belongs_to :person 関連付けを定義するクラスは、「person_id」をデフォルトの :foreign_key として使用します。同様に、 belongs_to :favorite_person, :class_name => "Person" は "favorite_person_id" の外部キーを使用します。

同様に、あなたは を割り当てますmessage.sender = User.firstが、あなたのMessageモデルには がなくsendersenders(複数) があります。これが、コンソールにエラーが表示される理由です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

正直なところ、このテストの意味がよくわかりません。メッセージに複数の送信者がいる理由もよくわかりません。これは単純な 1 対多の関係であるべきではありませんか? つまり、メッセージhas_one :senderです。それは私には理にかなっています。実際、ここでのモデルのセットアップ全体は少し混乱しています。なぜこのようにセットアップしたのかを明確にしていただけると助かります。

于 2012-12-05T00:08:19.877 に答える