Rails模型与橄榄球运动员的关系

时间:2015-09-22 08:57:26

标签: ruby-on-rails ruby activerecord database-design rails-activerecord

我在我的rails 4.2.4项目中有两个模型我想加入,我正在努力创建两者之间的正确关系。 有问题的域名是橄榄球,代码全部可在https://github.com/rgbycch/rgbycch-rest/tree/rails获得。模型是:

Playerhttps://github.com/rgbycch/rgbycch-rest/blob/rails/app/models/player.rbPlayerPositionhttps://github.com/rgbycch/rgbycch-rest/blob/rails/app/models/player_position.rb

我希望能够创建一种关系,Player可以拥有多个有利的PlayingPosition。我相信我的数据库结构需要看起来像这样:

create_table :favoured_positions do |t|
  t.references :player, index: true, foreign_key: true # fk to player table
  t.references :player_position, index: true, foreign_key: true # fk to player_position table
  t.integer :num_favs # additional data for a favored playing position

  t.timestamps null: false
end

我可以像这样生成一个新的FavoredPosition模型:

bundle exec bin/rails generate model FavouredPosition player:references player_position:references num_favs:integer

生成一个类似于以下的类:

class FavouredPosition < ActiveRecord::Base
  belongs_to :player
  belongs_to :player_position
end

我不确定如何更改我的PlayerPlayerPosition模型以反映这种新关系。以下是正确的:

class Player < ActiveRecord::Base
  has_many :favored_positions, :through => :favoured_positions
end

class PlayerPositions < ActiveRecord::Base
  has_many :favored_playing_positions, :through => :favoured_positions
end

您是否建议我将索引添加到其中任何一个表中?

谢谢,

肖恩

2 个答案:

答案 0 :(得分:2)

您需要设置如下关联:

class Player < ActiveRecord::Base
  has_many :favoured_positions
  has_many :player_positions, through: :favoured_positions
end

class PlayerPosition < ActiveRecord::Base
  has_many :favoured_positions
  has_many :players, through: :favoured_positions
end

请参阅:http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

答案 1 :(得分:1)

首先,将PlayerPosition更改为Position,它更简单,适用于DRY (Don't Repeat Yourself) principle

其次,您所指的是ActiveRecord association。这些基本上是ActiveRecord ORM允许您在Rails中关联对象的方式。

-

has_many :through

enter image description here

我认为您最适​​合使用的关联可能是has_many :throughhas_and_belongs_to_many。既然您已经has_many :through投放了,那么您需要做什么:

#app/models/player.rb
class Player < ActiveRecord::Base
    #columns id | etc | etc | created_at | updated_at
    has_many :favoured_positions
    has_many :positions, through: :favoured_positions
end

#app/models/position.rb
class Position < ActiveRecord::Base
   #columns id | etc | etc | created_at | updated_at
   has_many :favoured_positions
   has_many :players, through: :favoured_positions
end

#app/models/favoured_position.rb
class FavouredPosition < ActiveRecord::Base
   #columns id | position_id | player_id | any | other | column | created_at | updated_at
   belongs_to :position
   belongs_to :player
end

-

has_and_belongs_to_many

enter image description here

关于has_many :throughhas_and_belongs_to_many之间差异的重要警告。如果您没有favoured_positions加入模型中有任何额外的列,我建议您使用has_and_belongs_to_many。它比你需要的要简单得多:

#app/models/player.rb
class Player < ActiveRecord::Base
  has_and_belongs_to_many :positions
end

#app/models/position.rb
class Position < ActiveRecord::Base
   has_and_belongs_to_many :players
end

然后您按如下方式创建一个联接表:

#players_positions
player_id | position_id