1

我想对从用户到投注的投注系统关系建模。我想要一个带有两个主键的模型 Bet。

这是我的迁移:

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 ...)?

感谢您的帮助。

4

2 回答 2

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

于 2010-03-29T18:13:21.490 回答
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
于 2010-03-29T18:17:27.020 回答