2010-03-29 67 views
1

我想模擬從用戶到投注的投注系統關係。我想要一個有兩個主鍵的模型賭注。當添加記錄關係時,「TypeError:無法將符號轉換爲字符串」

這裏是我的遷移:

class CreateBets < ActiveRecord::Migration 
    def self.up 
    create_table :bets do |t| 
     t.integer :user_1_id 
     t.integer :user_2_id 
     t.integer :amount 

     t.timestamps 
    end 
    end 
end 

class CreateUsers < ActiveRecord::Migration 
    def self.up 
    create_table :users do |t| 
     t.string :name 
     t.timestamps 
    end 
    end 
end 

的車型:

class Bet < ActiveRecord::Base 
    belongs_to :user_1,:class_name=>:User 
    belongs_to :user_2,:class_name=>:User 

end 

class User < ActiveRecord::Base 
    has_many :bets, :foreign_key =>:user_1 
    has_many :bets, :foreign_key =>:user_2 
end 

當我在控制檯測試在這裏我的關係我得到一個錯誤

>> u1=User.create :name=>"aa" 
=> #<User id: 3, name: "aa", created_at: "2010-03-29 05:35:21", updated_at: "2010-03-29 05:35:21"> 
>> u2=User.create :name=>"bb" 
=> #<User id: 4, name: "bb", created_at: "2010-03-29 05:35:29", updated_at: "2010-03-29 05:35:29"> 
>> b=Bet.create(:user_1=>u1,:user_2=>u2) 
**************error************ 
TypeError: can't convert Symbol into String 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/base.rb:2049:in `class_eval' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/base.rb:2049:in `compute_type' 
from /home/fenec/sources/BetTest/vendor/rails/activesupport/lib/active_support/core_ext/kernel/reporting.rb:11:in `silence_warnings' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/base.rb:2047:in `compute_type' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/reflection.rb:151:in `send' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/reflection.rb:151:in `klass' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:254:in `raise_on_type_mismatch' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/associations/belongs_to_association.rb:22:in `replace' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/associations.rb:1276:in `user_1=' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/base.rb:2589:in `send' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/base.rb:2589:in `attributes=' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/base.rb:2585:in `each' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/base.rb:2585:in `attributes=' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/base.rb:2285:in `initialize' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/base.rb:691:in `new' 
from /home/fenec/sources/BetTest/vendor/rails/activerecord/lib/active_record/base.rb:691:in `create' 

問題:

  1. 如何正確定義這些表之間的關係 ?
  2. 是否有任何約定來命名屬性(例如:user_1_id ...)?

謝謝你的幫助。

+0

爲什麼打賭需要有兩個用戶連接到它? 清理你的例子還是值得的,它們很難閱讀。 – Delameko 2010-03-29 10:50:44

+0

現在這個帖子很乾淨,謝謝 – fenec 2010-03-29 18:11:33

+0

把兩個用戶存放在db中的兩個字段真的很奇怪。我建議實施has_many:用戶解決方案,驗證用戶數(不是更多,或者確切地說每個下注有2個用戶) – fl00r 2010-03-29 18:24:34

回答

3

這裏的問題是:

class Bet < ActiveRecord::Base 
    belongs_to :user_1, :class_name=> "User", :foreign_key => 'user_1_id' 
    belongs_to :user_2, :class_name=> "User", :foreign_key => 'user_2_id' 
end 

你沒有設置你的foreign_keys。他們不是USER_1,user_2,但user_1_id,user_1_id - 同樣在遷移

用戶模式:

class User < ActiveRecord::Base 
    def bets 
    Bet.all :conditions => ['user_1_id = ? or user_2_id = ?', self.id, self.id] 
    end 
end 

,或者您可以使用with_scope

+0

即使我使用您發佈的語法,它也不起作用! – fenec 2010-03-29 19:17:07

+0

嘗試b = Bet.new; b.user_1 = u1; b.user_2 = u2; – fl00r 2010-03-29 19:45:20

+0

它仍在報錯: >> b.user_1 = u1 TypeError:無法將符號轉換爲字符串 – fenec 2010-03-29 20:07:42

1

我會使用一個連接表這個。我沒有測試這個代碼或者檢查語法,但是它至少應該指向正確的方向。您可以使用驗證來確保每次下注最多有2個用戶。

class CreateBets < ActiveRecord::Migration 
    def self.up 
    create_table :bets do |t| 

     t.integer :amount 
     t.timestamps 
    end 
    end 
end 

class CreateUserBets < ActiveRecord::Migration 
    def self.up 
    create_table :users do |t| 
     t.integer :user_id 
     t.integer :bet_id 
     t.timestamps 
    end 
    end 
end 

class CreateUsers < ActiveRecord::Migration 
    def self.up 
    create_table :users do |t| 
     t.string :name 
     t.timestamps 
    end 
    end 
end 

class User < ActiveRecord::Base 
    has_many :bets, :through => :user_bets 
end 

class Bet < ActiveRecord::Base 
    has_man :users, :through => :user_bets 
end